view_component_reflex 2.6.1 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +31 -2
- data/app/components/view_component_reflex/component.rb +7 -16
- data/lib/view_component_reflex/engine.rb +9 -6
- data/lib/view_component_reflex/reflex.rb +29 -6
- data/lib/view_component_reflex/reflex_factory.rb +9 -3
- data/lib/view_component_reflex/state_adapter/memory.rb +20 -5
- data/lib/view_component_reflex/version.rb +1 -1
- metadata +18 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec3bf329ad0e7bbc776b52761cadec00a33ab1c78fba847d26271b27e8a30532
|
4
|
+
data.tar.gz: 5b6d10305c220bbd86486d513b97091e88afa87d6b0b91669c95d04cb1539fb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44151d570ece600f3151acffd7eb7ff7a382bc26ac36d088683c7de6439d8335643742aeb5a9de337f19646967f913678402d39a2b11baef7506d1af3beb2eef
|
7
|
+
data.tar.gz: 8de0f26c998b8a1061829128d4f5a8175ae11d3a115b2e676af6d6af3a5896150cb32b72df295a53c75d83009dbaaba136bf638dd125e1d69c56dd1a38200702
|
data/README.md
CHANGED
@@ -207,7 +207,7 @@ end
|
|
207
207
|
```
|
208
208
|
|
209
209
|
## Custom reflex base class
|
210
|
-
Reflexes typically inherit from a base ApplicationReflex. You can define the base class for a view_component_reflex by using the `reflex_base_class`
|
210
|
+
Reflexes typically inherit from a base ApplicationReflex. You can define the base class for a view_component_reflex by using the `reflex_base_class` accessor.
|
211
211
|
The parent class must inherit ViewComponentReflex::Reflex, and will throw an error if it does not.
|
212
212
|
|
213
213
|
```ruby
|
@@ -217,7 +217,7 @@ end
|
|
217
217
|
|
218
218
|
|
219
219
|
class MyComponent < ViewComponentReflex::Component
|
220
|
-
reflex_base_class ApplicationReflex
|
220
|
+
MyComponent.reflex_base_class = ApplicationReflex
|
221
221
|
end
|
222
222
|
```
|
223
223
|
|
@@ -359,6 +359,35 @@ end
|
|
359
359
|
|
360
360
|
StimulusReflex 3.4 introduced a fix that merges the current `request.env` and provides the CSRF token to fetch the session.
|
361
361
|
|
362
|
+
## Help, my instance variables do not persist into the session
|
363
|
+
|
364
|
+
These instance variable names are not working and unsafe:
|
365
|
+
|
366
|
+
```rb
|
367
|
+
def unsafe_instance_variables
|
368
|
+
[
|
369
|
+
:@view_context, :@lookup_context, :@view_renderer, :@view_flow,
|
370
|
+
:@virtual_path, :@variant, :@current_template, :@output_buffer, :@key,
|
371
|
+
:@helpers, :@controller, :@request, :@tag_builder, :@initialized_state
|
372
|
+
]
|
373
|
+
end
|
374
|
+
```
|
375
|
+
Please use a different name to be able to save them to the session.
|
376
|
+
|
377
|
+
## Anycable
|
378
|
+
|
379
|
+
@sebyx07 provided a solution to use anycable (https://github.com/joshleblanc/view_component_reflex/issues/23#issue-721786338)
|
380
|
+
|
381
|
+
Leaving this, might help others:
|
382
|
+
|
383
|
+
I tried this with any cable and I had to add this to development.rb
|
384
|
+
Otherwise @instance_variables were nil after a reflex
|
385
|
+
|
386
|
+
```ruby
|
387
|
+
config.cache_store = :redis_cache_store, { url: "redis://localhost:6379/1", driver: :hiredis }
|
388
|
+
config.session_store :cache_store
|
389
|
+
```
|
390
|
+
|
362
391
|
## License
|
363
392
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
364
393
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module ViewComponentReflex
|
2
2
|
class Component < ViewComponent::Base
|
3
|
+
class_attribute :reflex_base_class, default: ViewComponentReflex::Reflex
|
4
|
+
|
3
5
|
class << self
|
4
6
|
def init_stimulus_reflex
|
5
7
|
factory = ViewComponentReflex::ReflexFactory.new(self)
|
@@ -7,18 +9,6 @@ module ViewComponentReflex
|
|
7
9
|
wire_up_callbacks if factory.new?
|
8
10
|
end
|
9
11
|
|
10
|
-
def reflex_base_class(new_base_class = nil)
|
11
|
-
if new_base_class.nil?
|
12
|
-
@reflex_base_class ||= ViewComponentReflex::Reflex
|
13
|
-
else
|
14
|
-
if new_base_class <= ViewComponentReflex::Reflex
|
15
|
-
@reflex_base_class = new_base_class
|
16
|
-
else
|
17
|
-
raise StandardError.new("The reflex base class must inherit from ViewComponentReflex::Reflex")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
12
|
def queue_callback(key, args, blk)
|
23
13
|
callbacks(key).push({
|
24
14
|
args: args,
|
@@ -151,7 +141,7 @@ module ViewComponentReflex
|
|
151
141
|
adapter = ViewComponentReflex::Engine.state_adapter
|
152
142
|
|
153
143
|
# initialize session state
|
154
|
-
if !stimulus_reflex? || adapter.state(request, @key).empty?
|
144
|
+
if (!stimulus_reflex? || adapter.state(request, @key).empty?) && !@initialized_state
|
155
145
|
|
156
146
|
new_state = create_safe_state
|
157
147
|
|
@@ -179,13 +169,14 @@ module ViewComponentReflex
|
|
179
169
|
end
|
180
170
|
end
|
181
171
|
after_state_initialized(parameters_changed)
|
182
|
-
@initialized_state = true
|
183
172
|
end
|
173
|
+
|
174
|
+
@initialized_state = true
|
184
175
|
@key
|
185
176
|
end
|
186
177
|
|
187
178
|
def safe_instance_variables
|
188
|
-
instance_variables - unsafe_instance_variables
|
179
|
+
instance_variables - unsafe_instance_variables - omitted_from_state
|
189
180
|
end
|
190
181
|
|
191
182
|
private
|
@@ -203,7 +194,7 @@ module ViewComponentReflex
|
|
203
194
|
|
204
195
|
# this will almost certainly break
|
205
196
|
safe_instance_variables.each do |k|
|
206
|
-
new_state[k] = instance_variable_get(k)
|
197
|
+
new_state[k] = instance_variable_get(k)
|
207
198
|
end
|
208
199
|
new_state
|
209
200
|
end
|
@@ -13,13 +13,16 @@ module ViewComponentReflex
|
|
13
13
|
reflex_name, _ = target.split("#")
|
14
14
|
reflex_name = reflex_name.camelize
|
15
15
|
component_name = reflex_name.end_with?("Reflex") ? reflex_name[0...-6] : reflex_name
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
16
|
+
component = begin
|
17
|
+
component_name.constantize
|
18
|
+
rescue
|
19
|
+
# Since every reflex runs through this monkey patch, we're just going to ignore the ones that aren't for components
|
20
|
+
end
|
22
21
|
|
22
|
+
if component&.respond_to?(:init_stimulus_reflex)
|
23
|
+
component.init_stimulus_reflex
|
24
|
+
else
|
25
|
+
p "Tried to initialize view_component_reflex on #{component_name}, but it's not a view_component_reflex"
|
23
26
|
end
|
24
27
|
receive_original(data)
|
25
28
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module ViewComponentReflex
|
2
2
|
class Reflex < StimulusReflex::Reflex
|
3
|
-
include CableReady::Broadcaster
|
4
3
|
|
5
4
|
class << self
|
6
5
|
attr_accessor :component_class
|
@@ -15,16 +14,26 @@ module ViewComponentReflex
|
|
15
14
|
if primary_selector
|
16
15
|
prevent_refresh!
|
17
16
|
|
18
|
-
controller.process(
|
17
|
+
controller.process(params[:action])
|
19
18
|
document = Nokogiri::HTML(controller.response.body)
|
20
19
|
[primary_selector, *rest].each do |s|
|
21
20
|
html = document.css(s)
|
22
21
|
if html.present?
|
23
|
-
|
22
|
+
CableReady::Channels.instance[stream_name].morph(
|
24
23
|
selector: s,
|
25
24
|
html: html.inner_html,
|
26
25
|
children_only: true,
|
27
|
-
permanent_attribute_name: "data-reflex-permanent"
|
26
|
+
permanent_attribute_name: "data-reflex-permanent",
|
27
|
+
stimulus_reflex: {
|
28
|
+
reflex_id: reflex_id,
|
29
|
+
xpath: xpath,
|
30
|
+
c_xpath: c_xpath,
|
31
|
+
target: target,
|
32
|
+
reflex_controller: reflex_controller,
|
33
|
+
url: url,
|
34
|
+
morph: :page,
|
35
|
+
attrs: {key: element.dataset[:key]}
|
36
|
+
}
|
28
37
|
)
|
29
38
|
end
|
30
39
|
end
|
@@ -41,14 +50,28 @@ module ViewComponentReflex
|
|
41
50
|
end
|
42
51
|
end
|
43
52
|
document = Nokogiri::HTML(component.render_in(controller.view_context))
|
44
|
-
|
53
|
+
CableReady::Channels.instance[stream_name].morph(
|
45
54
|
selector: selector,
|
46
55
|
children_only: true,
|
47
56
|
html: document.css(selector).inner_html,
|
48
|
-
permanent_attribute_name: "data-reflex-permanent"
|
57
|
+
permanent_attribute_name: "data-reflex-permanent",
|
58
|
+
stimulus_reflex: {
|
59
|
+
reflex_id: reflex_id,
|
60
|
+
xpath: xpath,
|
61
|
+
target: target,
|
62
|
+
c_xpath: c_xpath,
|
63
|
+
reflex_controller: reflex_controller,
|
64
|
+
url: url,
|
65
|
+
morph: :page,
|
66
|
+
attrs: {key: element.dataset[:key]}
|
67
|
+
}
|
49
68
|
)
|
50
69
|
end
|
51
70
|
|
71
|
+
def target
|
72
|
+
"#{component_class}##{method_name}"
|
73
|
+
end
|
74
|
+
|
52
75
|
def refresh_all!
|
53
76
|
refresh!("body")
|
54
77
|
end
|
@@ -35,11 +35,17 @@ module ViewComponentReflex
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def reflex_from_nested_component
|
38
|
-
if @component.module_parent
|
39
|
-
@component.module_parent
|
38
|
+
parent = if @component.respond_to? :module_parent
|
39
|
+
@component.module_parent
|
40
|
+
else
|
41
|
+
@component.parent
|
42
|
+
end
|
43
|
+
|
44
|
+
if parent.const_defined?(reflex_name)
|
45
|
+
parent.const_get(reflex_name)
|
40
46
|
else
|
41
47
|
@new = true
|
42
|
-
|
48
|
+
parent.const_set(reflex_name, reflex_instance)
|
43
49
|
end
|
44
50
|
end
|
45
51
|
|
@@ -3,8 +3,10 @@ module ViewComponentReflex
|
|
3
3
|
module StateAdapter
|
4
4
|
class Memory
|
5
5
|
def self.state(request, key)
|
6
|
-
|
7
|
-
|
6
|
+
id = extract_id(request)
|
7
|
+
|
8
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE[id] ||= {}
|
9
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE[id][key] ||= {}
|
8
10
|
end
|
9
11
|
|
10
12
|
def self.set_state(request, _, key, new_state)
|
@@ -14,16 +16,29 @@ module ViewComponentReflex
|
|
14
16
|
end
|
15
17
|
|
16
18
|
def self.store_state(request, key, new_state = {})
|
17
|
-
|
18
|
-
|
19
|
+
id = extract_id(request)
|
20
|
+
|
21
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE[id] ||= {}
|
22
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE[id][key] = {}
|
19
23
|
new_state.each do |k, v|
|
20
|
-
VIEW_COMPONENT_REFLEX_MEMORY_STATE[
|
24
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE[id][key][k] = v
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
24
28
|
def self.wrap_write_async
|
25
29
|
yield
|
26
30
|
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def self.extract_id(request)
|
35
|
+
session = request&.session
|
36
|
+
if session.respond_to? :id
|
37
|
+
session.id.to_s
|
38
|
+
else
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
end
|
27
42
|
end
|
28
43
|
end
|
29
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: view_component_reflex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua LeBlanc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -36,20 +36,14 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 3.
|
40
|
-
- - "<"
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: '3.4'
|
39
|
+
version: 3.4.0
|
43
40
|
type: :runtime
|
44
41
|
prerelease: false
|
45
42
|
version_requirements: !ruby/object:Gem::Requirement
|
46
43
|
requirements:
|
47
44
|
- - ">="
|
48
45
|
- !ruby/object:Gem::Version
|
49
|
-
version: 3.
|
50
|
-
- - "<"
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: '3.4'
|
46
|
+
version: 3.4.0
|
53
47
|
- !ruby/object:Gem::Dependency
|
54
48
|
name: view_component
|
55
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -64,6 +58,20 @@ dependencies:
|
|
64
58
|
- - ">="
|
65
59
|
- !ruby/object:Gem::Version
|
66
60
|
version: '0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: sqlite3
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
67
75
|
description: Allow stimulus reflexes in a view component
|
68
76
|
email:
|
69
77
|
- joshleblanc94@gmail.com
|