stimulus_reflex 2.0.0 → 2.0.1
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.
- checksums.yaml +4 -4
- data/CODE_OF_CONDUCT.md +76 -0
- data/Gemfile.lock +7 -7
- data/README.md +104 -218
- data/README.md.orig +132 -98
- data/Rakefile +6 -1
- data/SUMMARY.md +7 -0
- data/bin/standardize +1 -1
- data/lib/stimulus_reflex/channel.rb +20 -8
- data/lib/stimulus_reflex/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb76c0066092e1f7ee8db5642f38b41c2c7f0e6718ab87c6a3358833fbe9b685
|
|
4
|
+
data.tar.gz: 79bb331fcce6f043d1098e41bf0a373c277138fadb0963784f58825fe5786309
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c55bc084dbf1e05f799a0a17e1d94a11951d79574a1b89492fabfa8c884d4e1e44aa1f9d9223462f043b5ca8f23a7a0f068939d9a0ac1aff53959d07fa0dbddd
|
|
7
|
+
data.tar.gz: 360e7909ab6bf950c426e18de0ed857f65b1fb5c51ce77cf19f8644420f6cd798b79f803f8cf7485c02d6f77c245c88f7326846d37d787d0728e68c8b1e0eb13
|
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
|
8
|
+
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
|
9
|
+
level of experience, education, socio-economic status, nationality, personal
|
|
10
|
+
appearance, race, religion, or sexual identity and orientation.
|
|
11
|
+
|
|
12
|
+
## Our Standards
|
|
13
|
+
|
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
|
15
|
+
include:
|
|
16
|
+
|
|
17
|
+
- Using welcoming and inclusive language
|
|
18
|
+
- Being respectful of differing viewpoints and experiences
|
|
19
|
+
- Gracefully accepting constructive criticism
|
|
20
|
+
- Focusing on what is best for the community
|
|
21
|
+
- Showing empathy towards other community members
|
|
22
|
+
|
|
23
|
+
Examples of unacceptable behavior by participants include:
|
|
24
|
+
|
|
25
|
+
- The use of sexualized language or imagery and unwelcome sexual attention or
|
|
26
|
+
advances
|
|
27
|
+
- Trolling, insulting/derogatory comments, and personal or political attacks
|
|
28
|
+
- Public or private harassment
|
|
29
|
+
- Publishing others' private information, such as a physical or electronic
|
|
30
|
+
address, without explicit permission
|
|
31
|
+
- Other conduct which could reasonably be considered inappropriate in a
|
|
32
|
+
professional setting
|
|
33
|
+
|
|
34
|
+
## Our Responsibilities
|
|
35
|
+
|
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
|
38
|
+
response to any instances of unacceptable behavior.
|
|
39
|
+
|
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
|
44
|
+
threatening, offensive, or harmful.
|
|
45
|
+
|
|
46
|
+
## Scope
|
|
47
|
+
|
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
|
49
|
+
when an individual is representing the project or its community. Examples of
|
|
50
|
+
representing a project or community include using an official project e-mail
|
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
|
53
|
+
further defined and clarified by project maintainers.
|
|
54
|
+
|
|
55
|
+
## Enforcement
|
|
56
|
+
|
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
58
|
+
reported by contacting the project team at natehop@gmail.com. All
|
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
|
63
|
+
|
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
|
66
|
+
members of the project's leadership.
|
|
67
|
+
|
|
68
|
+
## Attribution
|
|
69
|
+
|
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
71
|
+
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
|
72
|
+
|
|
73
|
+
[homepage]: https://www.contributor-covenant.org
|
|
74
|
+
|
|
75
|
+
For answers to common questions about this code of conduct, see
|
|
76
|
+
https://www.contributor-covenant.org/faq
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
stimulus_reflex (2.0.
|
|
4
|
+
stimulus_reflex (2.0.1)
|
|
5
5
|
cable_ready (>= 4.0.3)
|
|
6
6
|
nokogiri
|
|
7
7
|
rack
|
|
@@ -67,12 +67,12 @@ GEM
|
|
|
67
67
|
zeitwerk (~> 2.1, >= 2.1.8)
|
|
68
68
|
ast (2.4.0)
|
|
69
69
|
builder (3.2.3)
|
|
70
|
-
cable_ready (4.0.
|
|
70
|
+
cable_ready (4.0.5)
|
|
71
71
|
rails (>= 5.2)
|
|
72
72
|
coderay (1.1.2)
|
|
73
73
|
concurrent-ruby (1.1.5)
|
|
74
74
|
crass (1.0.4)
|
|
75
|
-
erubi (1.
|
|
75
|
+
erubi (1.9.0)
|
|
76
76
|
globalid (0.4.2)
|
|
77
77
|
activesupport (>= 4.2.0)
|
|
78
78
|
i18n (1.6.0)
|
|
@@ -89,12 +89,12 @@ GEM
|
|
|
89
89
|
mimemagic (0.3.3)
|
|
90
90
|
mini_mime (1.0.2)
|
|
91
91
|
mini_portile2 (2.4.0)
|
|
92
|
-
minitest (5.
|
|
93
|
-
nio4r (2.5.
|
|
92
|
+
minitest (5.12.0)
|
|
93
|
+
nio4r (2.5.2)
|
|
94
94
|
nokogiri (1.10.4)
|
|
95
95
|
mini_portile2 (~> 2.4.0)
|
|
96
96
|
parallel (1.17.0)
|
|
97
|
-
parser (2.6.4.
|
|
97
|
+
parser (2.6.4.1)
|
|
98
98
|
ast (~> 2.4.0)
|
|
99
99
|
pry (0.12.2)
|
|
100
100
|
coderay (~> 1.1.0)
|
|
@@ -149,7 +149,7 @@ GEM
|
|
|
149
149
|
actionpack (>= 4.0)
|
|
150
150
|
activesupport (>= 4.0)
|
|
151
151
|
sprockets (>= 3.0.0)
|
|
152
|
-
standard (0.1.
|
|
152
|
+
standard (0.1.4)
|
|
153
153
|
rubocop (~> 0.72.0)
|
|
154
154
|
rubocop-performance (~> 1.4.0)
|
|
155
155
|
standardrb (1.0.0)
|
data/README.md
CHANGED
|
@@ -1,132 +1,95 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-

|
|
1
|
+
---
|
|
2
|
+
description: Ensure your projects are fast to market... with a small team
|
|
3
|
+
---
|
|
5
4
|
|
|
6
5
|
# StimulusReflex
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
### Build reactive [Single Page Applications (SPAs)](https://en.wikipedia.org/wiki/Single-page_application) with [Rails](https://rubyonrails.org) and [Stimulus](https://stimulusjs.org)
|
|
11
|
-
|
|
12
|
-
This project supports building [reactive applications](https://en.wikipedia.org/wiki/Reactive_programming)
|
|
13
|
-
with the Rails tooling you already know and love.
|
|
14
|
-
It's designed to work perfectly with [server rendered HTML](https://guides.rubyonrails.org/action_view_overview.html),
|
|
15
|
-
[Russian doll caching](https://edgeguides.rubyonrails.org/caching_with_rails.html#russian-doll-caching),
|
|
16
|
-
[Stimulus](https://stimulusjs.org), [Turbolinks](https://www.youtube.com/watch?v=SWEts0rlezA), etc...
|
|
17
|
-
|
|
18
|
-
__No need for a complex front-end framework. No need to grow your team or duplicate your efforts.__
|
|
19
|
-
|
|
20
|
-
_Inspired by [Phoenix LiveView](https://youtu.be/Z2DU0qLfPIY?t=670)._ 🙌
|
|
21
|
-
|
|
22
|
-
## Table of Contents
|
|
23
|
-
|
|
24
|
-
<!-- toc -->
|
|
25
|
-
|
|
26
|
-
- [Before you Begin](#before-you-begin)
|
|
27
|
-
- [How it Works](#how-it-works)
|
|
28
|
-
- [Setup](#setup)
|
|
29
|
-
* [JavaScript](#javascript)
|
|
30
|
-
+ [app/javascript/controllers/index.js](#appjavascriptcontrollersindexjs)
|
|
31
|
-
* [Gemfile](#gemfile)
|
|
32
|
-
- [Usage](#usage)
|
|
33
|
-
* [Implicit Declarative Reflexes](#implicit-declarative-reflexes)
|
|
34
|
-
+ [app/views/pages/example.html.erb](#appviewspagesexamplehtmlerb)
|
|
35
|
-
+ [app/reflexes/example_reflex.rb](#appreflexesexample_reflexrb)
|
|
36
|
-
* [Explicitly Defined Reflexes](#explicitly-defined-reflexes)
|
|
37
|
-
+ [app/views/pages/example.html.erb](#appviewspagesexamplehtmlerb-1)
|
|
38
|
-
+ [app/javascript/controllers/example.js](#appjavascriptcontrollersexamplejs)
|
|
39
|
-
+ [app/reflexes/example_reflex.rb](#appreflexesexample_reflexrb-1)
|
|
40
|
-
- [What Just Happened](#what-just-happened)
|
|
41
|
-
- [Advanced Usage](#advanced-usage)
|
|
42
|
-
* [The Reflex `element` property](#the-reflex-element-property)
|
|
43
|
-
* [ActionCable](#actioncable)
|
|
44
|
-
+ [Performance](#performance)
|
|
45
|
-
+ [ActionCable Rooms](#actioncable-rooms)
|
|
46
|
-
* [Render Delay](#render-delay)
|
|
47
|
-
- [Demo Applications](#demo-applications)
|
|
48
|
-
- [Contributing](#contributing)
|
|
49
|
-
* [Coding Standards](#coding-standards)
|
|
50
|
-
* [Releasing](#releasing)
|
|
51
|
-
|
|
52
|
-
<!-- tocstop -->
|
|
7
|
+
###### Read this document on the [official docs site](https://docs.stimulusreflex.com).
|
|
53
8
|
|
|
54
|
-
|
|
9
|
+
[](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
|
|
10
|
+
[](https://codeclimate.com/github/hopsoft/stimulus_reflex/maintainability)
|
|
11
|
+

|
|
12
|
+

|
|
55
13
|
|
|
56
|
-
|
|
57
|
-
[UJS remote elements](https://guides.rubyonrails.org/working_with_javascript_in_rails.html#remote-elements)
|
|
58
|
-
, [Stimulus](https://stimulusjs.org), and [Turbolinks](https://github.com/turbolinks/turbolinks).
|
|
59
|
-
_Consider building with standard Rails tooling before introducing StimulusReflex._
|
|
60
|
-
_Check out the [Stimulus TodoMVC](https://github.com/hopsoft/stimulus_todomvc) example if you are unsure how to accomplish this._
|
|
14
|
+
**Build reactive applications with the Rails tooling you already know and love.** StimulusReflex is designed to work perfectly with [server rendered HTML](https://guides.rubyonrails.org/action_view_overview.html), [Russian doll caching](https://edgeguides.rubyonrails.org/caching_with_rails.html#russian-doll-caching), [Stimulus](https://stimulusjs.org/), [Turbolinks](https://www.youtube.com/watch?v=SWEts0rlezA), etc... and strives to live up to the vision outlined in [The Rails Doctrine](https://rubyonrails.org/doctrine/).
|
|
61
15
|
|
|
62
|
-
|
|
16
|
+
## Before you Begin
|
|
63
17
|
|
|
64
|
-
|
|
65
|
-
1. __The controller action is invoked directly__ _- skips framework overhead such as the middleware chain, etc..._
|
|
66
|
-
1. __DOM diffing is used to update the page__ _- provides faster rendering and less jitter_
|
|
18
|
+
A great user experience can be created with Rails alone. Tools like [UJS remote elements](https://guides.rubyonrails.org/working_with_javascript_in_rails.html#remote-elements) , [Stimulus](https://stimulusjs.org/), and [Turbolinks](https://github.com/turbolinks/turbolinks) are incredibly powerful when combined. Try building your application using these tools before introducing StimulusReflex.
|
|
67
19
|
|
|
68
|
-
|
|
20
|
+
{% hint style="info" %}
|
|
21
|
+
See the [Stimulus TodoMVC](https://github.com/hopsoft/stimulus_todomvc) example application if you are unsure how to do this.
|
|
22
|
+
{% endhint %}
|
|
69
23
|
|
|
70
|
-
|
|
71
|
-
1. Use [Stimulus](https://stimulusjs.org) and [ActionCable](https://edgeguides.rubyonrails.org/action_cable_overview.html) to invoke a method on the server
|
|
72
|
-
1. Watch the page automatically render updates via fast [DOM diffing](https://github.com/patrick-steele-idem/morphdom)
|
|
73
|
-
1. That's it...
|
|
24
|
+
## Benefits
|
|
74
25
|
|
|
75
|
-
|
|
76
|
-
There are no hidden gotchas.
|
|
26
|
+
StimulusReflex offers 3 primary benefits over the traditional Rails request/response cycle.
|
|
77
27
|
|
|
78
|
-
|
|
28
|
+
1. **All communication happens via web socket** - avoids the overhead of traditional HTTP connections
|
|
29
|
+
2. **The controller action is invoked directly** - skips framework overhead like the middleware chain
|
|
30
|
+
3. **DOM diffing is used to update the page** - provides faster rendering and less jitter
|
|
79
31
|
|
|
80
32
|
## Setup
|
|
81
33
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
```
|
|
34
|
+
```bash
|
|
85
35
|
yarn add stimulus_reflex
|
|
86
36
|
```
|
|
87
|
-
#### app/javascript/controllers/index.js
|
|
88
|
-
|
|
89
|
-
This is the file where Stimulus is initialized in your application.
|
|
90
|
-
_Note that your file location may be different._
|
|
91
37
|
|
|
38
|
+
{% code-tabs %}
|
|
39
|
+
{% code-tabs-item title="app/javascript/controllers/index.js" %}
|
|
92
40
|
```javascript
|
|
93
|
-
import { Application } from 'stimulus'
|
|
94
|
-
import { definitionsFromContext } from 'stimulus/webpack-helpers'
|
|
95
|
-
import StimulusReflex from 'stimulus_reflex'
|
|
96
|
-
|
|
97
|
-
const application = Application.start()
|
|
98
|
-
const context = require.context('controllers', true, /_controller\.js$/)
|
|
99
|
-
application.load(definitionsFromContext(context))
|
|
100
|
-
StimulusReflex.initialize(application)
|
|
41
|
+
import { Application } from 'stimulus'
|
|
42
|
+
import { definitionsFromContext } from 'stimulus/webpack-helpers'
|
|
43
|
+
import StimulusReflex from 'stimulus_reflex'
|
|
44
|
+
|
|
45
|
+
const application = Application.start()
|
|
46
|
+
const context = require.context('controllers', true, /_controller\.js$/)
|
|
47
|
+
application.load(definitionsFromContext(context))
|
|
48
|
+
StimulusReflex.initialize(application)
|
|
101
49
|
```
|
|
50
|
+
{% endcode-tabs-item %}
|
|
51
|
+
{% endcode-tabs %}
|
|
102
52
|
|
|
103
|
-
|
|
104
|
-
|
|
53
|
+
{% code-tabs %}
|
|
54
|
+
{% code-tabs-item title="Gemfile" %}
|
|
105
55
|
```ruby
|
|
106
56
|
gem "stimulus_reflex"
|
|
107
57
|
```
|
|
58
|
+
{% endcode-tabs-item %}
|
|
59
|
+
{% endcode-tabs %}
|
|
60
|
+
|
|
61
|
+
## Quick Start
|
|
108
62
|
|
|
109
|
-
|
|
63
|
+
Here are a few small contrived examples to get you started.
|
|
110
64
|
|
|
111
|
-
###
|
|
65
|
+
### No JavaScript
|
|
112
66
|
|
|
113
|
-
|
|
114
|
-
other than initializing StimulusReflex itself _([see the setup instructions](#javascript))_. Everything else is managed entirely by HTML and Ruby.
|
|
67
|
+
It's possible to build a reactive application without writing any JavaScript. This requires 2 steps.
|
|
115
68
|
|
|
116
|
-
|
|
69
|
+
1. Declare the appropriate data attributes in HTML.
|
|
70
|
+
2. Create a server side reflex object with Ruby.
|
|
117
71
|
|
|
118
|
-
|
|
72
|
+
This example will automatically update the page with the latest count whenever the anchor is clicked.
|
|
73
|
+
|
|
74
|
+
{% code-tabs %}
|
|
75
|
+
{% code-tabs-item title="app/views/pages/example.html.erb" %}
|
|
76
|
+
```text
|
|
119
77
|
<head></head>
|
|
120
78
|
<body>
|
|
121
|
-
<a href="#"
|
|
79
|
+
<a href="#"
|
|
80
|
+
data-reflex="click->ExampleReflex#increment"
|
|
81
|
+
data-step="1"
|
|
82
|
+
data-count="<%= @count.to_i %>">
|
|
122
83
|
Increment <%= @count.to_i %>
|
|
123
84
|
</a>
|
|
124
85
|
</body>
|
|
125
86
|
</html>
|
|
126
87
|
```
|
|
88
|
+
{% endcode-tabs-item %}
|
|
89
|
+
{% endcode-tabs %}
|
|
127
90
|
|
|
128
|
-
|
|
129
|
-
|
|
91
|
+
{% code-tabs %}
|
|
92
|
+
{% code-tabs-item title="app/reflexes/example\_reflex.rb" %}
|
|
130
93
|
```ruby
|
|
131
94
|
class ExampleReflex < StimulusReflex::Reflex
|
|
132
95
|
def increment
|
|
@@ -134,35 +97,46 @@ class ExampleReflex < StimulusReflex::Reflex
|
|
|
134
97
|
end
|
|
135
98
|
end
|
|
136
99
|
```
|
|
100
|
+
{% endcode-tabs-item %}
|
|
101
|
+
{% endcode-tabs %}
|
|
102
|
+
|
|
103
|
+
{% hint style="success" %}
|
|
104
|
+
**Concerns like managing state and template rendering are handled server side.** This technique works regardless of how complex the UI becomes. For example, we could render multiple instances of `@count` in unrelated sections of the page and they will all update.
|
|
105
|
+
{% endhint %}
|
|
137
106
|
|
|
138
|
-
|
|
107
|
+
{% hint style="danger" %}
|
|
108
|
+
Do not create server side reflex methods named `reflex` as this is a reserved word.
|
|
109
|
+
{% endhint %}
|
|
139
110
|
|
|
140
|
-
|
|
141
|
-
This technique works regardless of how complex the UI may become.
|
|
142
|
-
For example, we could render multiple instances of `@count` in unrelated sections of the page and they will all update.
|
|
111
|
+
### Some JavaScript
|
|
143
112
|
|
|
144
|
-
|
|
113
|
+
Real world applications typically warrant setting up finer grained control. This requires 3 steps.
|
|
145
114
|
|
|
146
|
-
|
|
147
|
-
|
|
115
|
+
1. Declare the appropriate data attributes in HTML.
|
|
116
|
+
2. Create a client side StimulusReflex controller with JavaScript.
|
|
117
|
+
3. Create a server side reflex object with Ruby.
|
|
148
118
|
|
|
149
|
-
|
|
119
|
+
This example will automatically update the page with the latest count whenever the anchor is clicked.
|
|
150
120
|
|
|
151
|
-
|
|
121
|
+
{% code-tabs %}
|
|
122
|
+
{% code-tabs-item title="app/views/pages/example.html.erb" %}
|
|
123
|
+
```text
|
|
152
124
|
<head></head>
|
|
153
125
|
<body>
|
|
154
|
-
<a href="#"
|
|
126
|
+
<a href="#"
|
|
127
|
+
data-controller="example"
|
|
128
|
+
data-action="click->example#increment">
|
|
155
129
|
Increment <%= @count.to_i %>
|
|
156
130
|
</a>
|
|
157
131
|
</body>
|
|
158
132
|
</html>
|
|
159
133
|
```
|
|
160
|
-
|
|
161
|
-
|
|
134
|
+
{% endcode-tabs-item %}
|
|
135
|
+
{% endcode-tabs %}
|
|
162
136
|
|
|
163
137
|
```javascript
|
|
164
|
-
import { Controller } from
|
|
165
|
-
import StimulusReflex from
|
|
138
|
+
import { Controller } from 'stimulus';
|
|
139
|
+
import StimulusReflex from 'stimulus_reflex';
|
|
166
140
|
|
|
167
141
|
export default class extends Controller {
|
|
168
142
|
connect() {
|
|
@@ -171,135 +145,47 @@ export default class extends Controller {
|
|
|
171
145
|
|
|
172
146
|
increment() {
|
|
173
147
|
// trigger a server-side reflex and a client-side page update
|
|
148
|
+
// pass the step argument with a value of `1` to the reflex method
|
|
174
149
|
this.stimulate('ExampleReflex#increment', 1);
|
|
175
150
|
}
|
|
176
151
|
}
|
|
177
152
|
```
|
|
178
153
|
|
|
179
|
-
|
|
180
|
-
|
|
154
|
+
{% code-tabs %}
|
|
155
|
+
{% code-tabs-item title="app/reflexes/example\_reflex.rb" %}
|
|
181
156
|
```ruby
|
|
182
157
|
class ExampleReflex < StimulusReflex::Reflex
|
|
183
158
|
def increment(step = 1)
|
|
184
|
-
|
|
159
|
+
# In a typical Rails app the Rails controller would set the value of @count
|
|
160
|
+
# after fetching it from a persistent data store
|
|
161
|
+
# @count = @count.to_i + step
|
|
162
|
+
|
|
163
|
+
# To keep this example simple, we use session to store the value
|
|
164
|
+
session[:count] = session[:count].to_i + step
|
|
165
|
+
@count = session[:count]
|
|
185
166
|
end
|
|
186
167
|
end
|
|
187
168
|
```
|
|
169
|
+
{% endcode-tabs-item %}
|
|
170
|
+
{% endcode-tabs %}
|
|
188
171
|
|
|
189
|
-
##
|
|
172
|
+
## How it Works
|
|
190
173
|
|
|
191
|
-
|
|
174
|
+
Here's what happens whenever a `StimulusReflex::Reflex` is invoked.
|
|
192
175
|
|
|
193
|
-
1. The page that triggered the reflex is re-rerendered.
|
|
176
|
+
1. The page that triggered the reflex is re-rerendered.
|
|
194
177
|
2. The re-rendered HTML is sent to the client over the ActionCable socket.
|
|
195
178
|
3. The page is updated via fast DOM diffing courtesy of morphdom.
|
|
196
179
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
### The Reflex `element` property
|
|
202
|
-
|
|
203
|
-
All reflex methods expose an `element` property.
|
|
204
|
-
This property holds a Hash like data structure that represents the HTML element that triggered the refelx.
|
|
205
|
-
It contains all of the Stimulus controller's
|
|
206
|
-
[DOM element attributes](https://developer.mozilla.org/en-US/docs/Web/API/Element/attributes) as well as other properties like `checked` and `value`.
|
|
207
|
-
_Most of the values will be strings._
|
|
208
|
-
|
|
209
|
-
```html
|
|
210
|
-
<checkbox id="example"
|
|
211
|
-
label="Example"
|
|
212
|
-
data-controller="checkbox"
|
|
213
|
-
data-value="123"
|
|
214
|
-
checked />
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
```ruby
|
|
218
|
-
class ExampleReflex < StimulusReflex::Reflex
|
|
219
|
-
def work()
|
|
220
|
-
element[:id] # => the HTML element's id attribute value
|
|
221
|
-
element.dataset # => a Hash that represents the HTML element's dataset
|
|
222
|
-
|
|
223
|
-
element[:id] # => "example"
|
|
224
|
-
element[:checked] # => true
|
|
225
|
-
element[:label] # => "Example"
|
|
226
|
-
element["data-controller"] # => "checkbox"
|
|
227
|
-
element["data-value"] # => "123"
|
|
228
|
-
element.dataset[:controller] # => "checkbox"
|
|
229
|
-
element.dataset[:value] # => "123"
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
- `element[:checked]` holds a boolean
|
|
235
|
-
- `element[:selected]` holds a boolean
|
|
236
|
-
- `element[:value]` holds the [DOM element's value](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#value)
|
|
237
|
-
- `select` elements assign `element[:value]` to their selected option's value
|
|
238
|
-
- `select` elements with _multiselect_ enabled assign `element[:values]` to their selected options values
|
|
239
|
-
- All other values exposed in `element` are extracted from the DOM element's attributes
|
|
240
|
-
|
|
241
|
-
### ActionCable
|
|
242
|
-
|
|
243
|
-
StimulusReflex will use the ActionCable defaults of `window.App` and `App.cable` if they exist.
|
|
244
|
-
If these defaults do not exist, StimulusReflex will establish a new socket connection.
|
|
245
|
-
|
|
246
|
-
#### Performance
|
|
247
|
-
|
|
248
|
-
ActionCable emits verbose log messages. Disabling ActionCable logs may improve performance.
|
|
249
|
-
|
|
250
|
-
```ruby
|
|
251
|
-
# config/application.rb
|
|
252
|
-
|
|
253
|
-
ActionCable.server.config.logger = Logger.new(nil)
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
#### ActionCable Rooms
|
|
257
|
-
|
|
258
|
-
You may find the need to restrict notifications to a specific room.
|
|
259
|
-
This can be accomplished by setting the `data-room` attribute on the StimulusController element.
|
|
260
|
-
|
|
261
|
-
```erb
|
|
262
|
-
<a href="#" data-controller="example" data-action="click->example#increment" data-room="12345">
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
### Render Delay
|
|
266
|
-
|
|
267
|
-
An attempt is made to reduce repaint/reflow jitter when users trigger lots of updates.
|
|
268
|
-
|
|
269
|
-
You can control how long to wait _(think debounce)_ prior to updating the page.
|
|
270
|
-
Simply set the `renderDelay` _(milliseconds)_ option when registering the controller.
|
|
271
|
-
|
|
272
|
-
```javascript
|
|
273
|
-
export default class extends Controller {
|
|
274
|
-
connect() {
|
|
275
|
-
StimulusReflex.register(this, {renderDelay: 200});
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
The default value is `25`.
|
|
281
|
-
|
|
282
|
-
## Demo Applications
|
|
283
|
-
|
|
284
|
-
Building apps with StimulusReflex should evoke your memories of the original [Rails demo video](https://www.youtube.com/watch?v=Gzj723LkRJY).
|
|
285
|
-
|
|
286
|
-
> Look at all the things I'm **not** doing. -DHH
|
|
287
|
-
|
|
288
|
-
- [TodoMVC](https://github.com/hopsoft/stimulus_reflex_todomvc)
|
|
289
|
-
|
|
290
|
-
## Contributing
|
|
180
|
+
{% hint style="success" %}
|
|
181
|
+
All instance variables created in the reflex are made available to the Rails controller and view.
|
|
182
|
+
{% endhint %}
|
|
291
183
|
|
|
292
|
-
|
|
184
|
+
{% hint style="info" %}
|
|
185
|
+
**The entire body is re-rendered and sent over the socket.** Smaller scoped DOM updates may come in a future release.
|
|
186
|
+
{% endhint %}
|
|
293
187
|
|
|
294
|
-
|
|
295
|
-
and [Prettier](https://github.com/prettier/prettier) to minimize bike shedding related to code formatting.
|
|
296
|
-
Please run `./bin/standardize` prior submitting pull requests.
|
|
188
|
+
## Example Applications
|
|
297
189
|
|
|
298
|
-
|
|
190
|
+
* [TodoMVC](https://stimulus-reflex-todomvc.herokuapp.com) - An implementation of [TodoMVC](http://todomvc.com/) using [Ruby on Rails](https://rubyonrails.org/), [StimulusJS](https://stimulusjs.org/), and [StimulusReflex](https://github.com/hopsoft/stimulus_reflex). [https://github.com/hopsoft/stimulus\_reflex\_todomvc](https://github.com/hopsoft/stimulus_reflex_todomvc)
|
|
299
191
|
|
|
300
|
-
1. Bump version number at `lib/stimulus_reflex/version.rb`
|
|
301
|
-
1. Run `rake build`
|
|
302
|
-
1. Run `rake release`
|
|
303
|
-
1. Change directories `cd ./javascript`
|
|
304
|
-
1. Run `yarn publish --tag GIT_TAG_CREATED_BY_RUBYGEMS`
|
|
305
|
-
1. Assign same version number to the JavaScript package _Might not be required?_
|
data/README.md.orig
CHANGED
|
@@ -1,74 +1,144 @@
|
|
|
1
|
-
|
|
1
|
+
<<<<<<< HEAD
|
|
2
|
+
[](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
|
|
2
3
|
[](https://codeclimate.com/github/hopsoft/stimulus_reflex/maintainability)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
=======
|
|
7
|
+
---
|
|
8
|
+
description: Ensure your projects are fast to market... with a small team
|
|
9
|
+
---
|
|
10
|
+
>>>>>>> master
|
|
3
11
|
|
|
4
12
|
# StimulusReflex
|
|
5
13
|
|
|
6
|
-
|
|
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
|
-
---
|
|
14
|
+
###### Read this document on the [official docs site](https://docs.stimulusreflex.com).
|
|
18
15
|
|
|
19
|
-
|
|
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.
|
|
16
|
+
**Build reactive applications with the Rails tooling you already know and love.** StimulusReflex is designed to work perfectly with [server rendered HTML](https://guides.rubyonrails.org/action_view_overview.html), [Russian doll caching](https://edgeguides.rubyonrails.org/caching_with_rails.html#russian-doll-caching), [Stimulus](https://stimulusjs.org/), [Turbolinks](https://www.youtube.com/watch?v=SWEts0rlezA), etc... and strives to live up to the vision outlined in [The Rails Doctrine](https://rubyonrails.org/doctrine/).
|
|
22
17
|
|
|
23
|
-
|
|
18
|
+
## Before you Begin
|
|
24
19
|
|
|
25
|
-
|
|
20
|
+
A great user experience can be created with Rails alone. Tools like [UJS remote elements](https://guides.rubyonrails.org/working_with_javascript_in_rails.html#remote-elements) , [Stimulus](https://stimulusjs.org/), and [Turbolinks](https://github.com/turbolinks/turbolinks) are incredibly powerful when combined. Try building your application using these tools before introducing StimulusReflex.
|
|
26
21
|
|
|
27
|
-
|
|
22
|
+
{% hint style="info" %}
|
|
23
|
+
See the [Stimulus TodoMVC](https://github.com/hopsoft/stimulus_todomvc) example application if you are unsure how to do this.
|
|
24
|
+
{% endhint %}
|
|
28
25
|
|
|
29
|
-
|
|
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...
|
|
26
|
+
## Benefits
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
There are no hidden gotchas.
|
|
28
|
+
StimulusReflex offers 3 primary benefits over the traditional Rails request/response cycle.
|
|
36
29
|
|
|
37
|
-
|
|
30
|
+
1. **All communication happens via web socket** - avoids the overhead of traditional HTTP connections
|
|
31
|
+
2. **The controller action is invoked directly** - skips framework overhead like the middleware chain
|
|
32
|
+
3. **DOM diffing is used to update the page** - provides faster rendering and less jitter
|
|
38
33
|
|
|
39
34
|
## Setup
|
|
40
35
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```
|
|
36
|
+
```bash
|
|
44
37
|
yarn add stimulus_reflex
|
|
45
38
|
```
|
|
46
39
|
|
|
47
|
-
|
|
40
|
+
{% code-tabs %}
|
|
41
|
+
{% code-tabs-item title="app/javascript/controllers/index.js" %}
|
|
42
|
+
```javascript
|
|
43
|
+
import { Application } from 'stimulus'
|
|
44
|
+
import { definitionsFromContext } from 'stimulus/webpack-helpers'
|
|
45
|
+
import StimulusReflex from 'stimulus_reflex'
|
|
46
|
+
|
|
47
|
+
const application = Application.start()
|
|
48
|
+
const context = require.context('controllers', true, /_controller\.js$/)
|
|
49
|
+
application.load(definitionsFromContext(context))
|
|
50
|
+
StimulusReflex.initialize(application)
|
|
51
|
+
```
|
|
52
|
+
{% endcode-tabs-item %}
|
|
53
|
+
{% endcode-tabs %}
|
|
48
54
|
|
|
55
|
+
{% code-tabs %}
|
|
56
|
+
{% code-tabs-item title="Gemfile" %}
|
|
49
57
|
```ruby
|
|
50
58
|
gem "stimulus_reflex"
|
|
51
59
|
```
|
|
60
|
+
{% endcode-tabs-item %}
|
|
61
|
+
{% endcode-tabs %}
|
|
62
|
+
|
|
63
|
+
## Quick Start
|
|
64
|
+
|
|
65
|
+
Here are a few small contrived examples to get you started.
|
|
52
66
|
|
|
53
|
-
|
|
67
|
+
### No JavaScript
|
|
54
68
|
|
|
55
|
-
|
|
69
|
+
It's possible to build a reactive application without writing any JavaScript. This requires 2 steps.
|
|
56
70
|
|
|
57
|
-
|
|
71
|
+
1. Declare the appropriate data attributes in HTML.
|
|
72
|
+
2. Create a server side reflex object with Ruby.
|
|
73
|
+
|
|
74
|
+
This example will automatically update the page with the latest count whenever the anchor is clicked.
|
|
75
|
+
|
|
76
|
+
{% code-tabs %}
|
|
77
|
+
{% code-tabs-item title="app/views/pages/example.html.erb" %}
|
|
78
|
+
```text
|
|
58
79
|
<head></head>
|
|
59
80
|
<body>
|
|
60
|
-
<a href="#"
|
|
81
|
+
<a href="#"
|
|
82
|
+
data-reflex="click->ExampleReflex#increment"
|
|
83
|
+
data-step="1"
|
|
84
|
+
data-count="<%= @count.to_i %>">
|
|
61
85
|
Increment <%= @count.to_i %>
|
|
62
86
|
</a>
|
|
63
87
|
</body>
|
|
64
88
|
</html>
|
|
65
89
|
```
|
|
90
|
+
{% endcode-tabs-item %}
|
|
91
|
+
{% endcode-tabs %}
|
|
92
|
+
|
|
93
|
+
{% code-tabs %}
|
|
94
|
+
{% code-tabs-item title="app/reflexes/example\_reflex.rb" %}
|
|
95
|
+
```ruby
|
|
96
|
+
class ExampleReflex < StimulusReflex::Reflex
|
|
97
|
+
def increment
|
|
98
|
+
@count = element.dataset[:count].to_i + element.dataset[:step].to_i
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
```
|
|
102
|
+
{% endcode-tabs-item %}
|
|
103
|
+
{% endcode-tabs %}
|
|
104
|
+
|
|
105
|
+
{% hint style="success" %}
|
|
106
|
+
**Concerns like managing state and template rendering are handled server side.** This technique works regardless of how complex the UI becomes. For example, we could render multiple instances of `@count` in unrelated sections of the page and they will all update.
|
|
107
|
+
{% endhint %}
|
|
66
108
|
|
|
67
|
-
|
|
109
|
+
{% hint style="danger" %}
|
|
110
|
+
Do not create server side reflex methods named `reflex` as this is a reserved word.
|
|
111
|
+
{% endhint %}
|
|
112
|
+
|
|
113
|
+
### Some JavaScript
|
|
114
|
+
|
|
115
|
+
Real world applications typically warrant setting up finer grained control. This requires 3 steps.
|
|
116
|
+
|
|
117
|
+
1. Declare the appropriate data attributes in HTML.
|
|
118
|
+
2. Create a client side StimulusReflex controller with JavaScript.
|
|
119
|
+
3. Create a server side reflex object with Ruby.
|
|
120
|
+
|
|
121
|
+
This example will automatically update the page with the latest count whenever the anchor is clicked.
|
|
122
|
+
|
|
123
|
+
{% code-tabs %}
|
|
124
|
+
{% code-tabs-item title="app/views/pages/example.html.erb" %}
|
|
125
|
+
```text
|
|
126
|
+
<head></head>
|
|
127
|
+
<body>
|
|
128
|
+
<a href="#"
|
|
129
|
+
data-controller="example"
|
|
130
|
+
data-action="click->example#increment">
|
|
131
|
+
Increment <%= @count.to_i %>
|
|
132
|
+
</a>
|
|
133
|
+
</body>
|
|
134
|
+
</html>
|
|
135
|
+
```
|
|
136
|
+
{% endcode-tabs-item %}
|
|
137
|
+
{% endcode-tabs %}
|
|
68
138
|
|
|
69
139
|
```javascript
|
|
70
|
-
import { Controller } from
|
|
71
|
-
import StimulusReflex from
|
|
140
|
+
import { Controller } from 'stimulus';
|
|
141
|
+
import StimulusReflex from 'stimulus_reflex';
|
|
72
142
|
|
|
73
143
|
export default class extends Controller {
|
|
74
144
|
connect() {
|
|
@@ -77,83 +147,47 @@ export default class extends Controller {
|
|
|
77
147
|
|
|
78
148
|
increment() {
|
|
79
149
|
// trigger a server-side reflex and a client-side page update
|
|
150
|
+
// pass the step argument with a value of `1` to the reflex method
|
|
80
151
|
this.stimulate('ExampleReflex#increment', 1);
|
|
81
152
|
}
|
|
82
153
|
}
|
|
83
154
|
```
|
|
84
155
|
|
|
85
|
-
|
|
86
|
-
|
|
156
|
+
{% code-tabs %}
|
|
157
|
+
{% code-tabs-item title="app/reflexes/example\_reflex.rb" %}
|
|
87
158
|
```ruby
|
|
88
159
|
class ExampleReflex < StimulusReflex::Reflex
|
|
89
160
|
def increment(step = 1)
|
|
90
|
-
|
|
161
|
+
# In a typical Rails app the Rails controller would set the value of @count
|
|
162
|
+
# after fetching it from a persistent data store
|
|
163
|
+
# @count = @count.to_i + step
|
|
164
|
+
|
|
165
|
+
# To keep this example simple, we use session to store the value
|
|
166
|
+
session[:count] = session[:count].to_i + step
|
|
167
|
+
@count = session[:count]
|
|
91
168
|
end
|
|
92
169
|
end
|
|
93
170
|
```
|
|
171
|
+
{% endcode-tabs-item %}
|
|
172
|
+
{% endcode-tabs %}
|
|
94
173
|
|
|
95
|
-
|
|
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
|
-
```
|
|
174
|
+
## How it Works
|
|
141
175
|
|
|
142
|
-
|
|
176
|
+
Here's what happens whenever a `StimulusReflex::Reflex` is invoked.
|
|
143
177
|
|
|
144
|
-
|
|
178
|
+
1. The page that triggered the reflex is re-rerendered.
|
|
179
|
+
2. The re-rendered HTML is sent to the client over the ActionCable socket.
|
|
180
|
+
3. The page is updated via fast DOM diffing courtesy of morphdom.
|
|
145
181
|
|
|
146
|
-
|
|
182
|
+
{% hint style="success" %}
|
|
183
|
+
All instance variables created in the reflex are made available to the Rails controller and view.
|
|
184
|
+
{% endhint %}
|
|
147
185
|
|
|
148
|
-
|
|
186
|
+
{% hint style="info" %}
|
|
187
|
+
**The entire body is re-rendered and sent over the socket.** Smaller scoped DOM updates may come in a future release.
|
|
188
|
+
{% endhint %}
|
|
149
189
|
|
|
150
|
-
|
|
190
|
+
## Example Applications
|
|
151
191
|
|
|
152
|
-
|
|
153
|
-
## Contributing
|
|
192
|
+
* [TodoMVC](https://stimulus-reflex-todomvc.herokuapp.com) - An implementation of [TodoMVC](http://todomvc.com/) using [Ruby on Rails](https://rubyonrails.org/), [StimulusJS](https://stimulusjs.org/), and [StimulusReflex](https://github.com/hopsoft/stimulus_reflex). [https://github.com/hopsoft/stimulus\_reflex\_todomvc](https://github.com/hopsoft/stimulus_reflex_todomvc)
|
|
154
193
|
|
|
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/Rakefile
CHANGED
data/SUMMARY.md
ADDED
data/bin/standardize
CHANGED
|
@@ -25,21 +25,27 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
|
25
25
|
element = StimulusReflex::Element.new(data["attrs"])
|
|
26
26
|
|
|
27
27
|
begin
|
|
28
|
-
|
|
28
|
+
reflex_class = reflex_name.constantize
|
|
29
|
+
raise ArgumentError.new("#{reflex_name} is not a StimulusReflex::Reflex") unless is_reflex?(reflex_class)
|
|
30
|
+
reflex = reflex_class.new(self, url: url, element: element)
|
|
29
31
|
delegate_call_to_reflex reflex, method_name, arguments
|
|
30
32
|
rescue => invoke_error
|
|
31
|
-
|
|
33
|
+
return broadcast_error("StimulusReflex::Channel Failed to invoke #{target}! #{url} #{invoke_error}", data)
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
begin
|
|
35
|
-
render_page_and_broadcast_morph url, reflex
|
|
37
|
+
render_page_and_broadcast_morph url, reflex, data
|
|
36
38
|
rescue => render_error
|
|
37
|
-
|
|
39
|
+
broadcast_error "StimulusReflex::Channel Failed to re-render #{url} #{render_error}", data
|
|
38
40
|
end
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
private
|
|
42
44
|
|
|
45
|
+
def is_reflex?(reflex_class)
|
|
46
|
+
reflex_class.ancestors.include? StimulusReflex::Reflex
|
|
47
|
+
end
|
|
48
|
+
|
|
43
49
|
def delegate_call_to_reflex(reflex, method_name, arguments = [])
|
|
44
50
|
method = reflex.method(method_name)
|
|
45
51
|
required_params = method.parameters.select { |(kind, _)| kind == :req }
|
|
@@ -54,9 +60,9 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
|
54
60
|
end
|
|
55
61
|
end
|
|
56
62
|
|
|
57
|
-
def render_page_and_broadcast_morph(url, reflex)
|
|
63
|
+
def render_page_and_broadcast_morph(url, reflex, data = {})
|
|
58
64
|
html = render_page(url, reflex)
|
|
59
|
-
broadcast_morph url, html if html.present?
|
|
65
|
+
broadcast_morph url, html, data if html.present?
|
|
60
66
|
end
|
|
61
67
|
|
|
62
68
|
def render_page(url, reflex)
|
|
@@ -90,9 +96,15 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
|
90
96
|
controller.response.body
|
|
91
97
|
end
|
|
92
98
|
|
|
93
|
-
def broadcast_morph(url, html)
|
|
99
|
+
def broadcast_morph(url, html, data = {})
|
|
94
100
|
html = extract_body_html(html)
|
|
95
|
-
cable_ready[stream_name].morph selector: "body", html: html, children_only: true
|
|
101
|
+
cable_ready[stream_name].morph selector: "body", html: html, children_only: true, stimulus_reflex: data
|
|
102
|
+
cable_ready.broadcast
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def broadcast_error(message, data = {})
|
|
106
|
+
logger.error "\e[31m#{message}\e[0m"
|
|
107
|
+
cable_ready[stream_name].dispatch_event name: "stimulus-reflex:500", detail: {stimulus_reflex: data.merge(error: message)}
|
|
96
108
|
cable_ready.broadcast
|
|
97
109
|
end
|
|
98
110
|
|
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: 2.0.
|
|
4
|
+
version: 2.0.1
|
|
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-09-
|
|
12
|
+
date: 2019-09-28 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rack
|
|
@@ -145,12 +145,14 @@ executables: []
|
|
|
145
145
|
extensions: []
|
|
146
146
|
extra_rdoc_files: []
|
|
147
147
|
files:
|
|
148
|
+
- CODE_OF_CONDUCT.md
|
|
148
149
|
- Gemfile
|
|
149
150
|
- Gemfile.lock
|
|
150
151
|
- LICENSE.txt
|
|
151
152
|
- README.md
|
|
152
153
|
- README.md.orig
|
|
153
154
|
- Rakefile
|
|
155
|
+
- SUMMARY.md
|
|
154
156
|
- bin/console
|
|
155
157
|
- bin/setup
|
|
156
158
|
- bin/standardize
|