view_component_reflex 1.6.1 → 1.7.0
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/README.md +7 -2
- data/app/components/view_component_reflex/component.rb +74 -29
- data/lib/view_component_reflex.rb +8 -7
- data/lib/view_component_reflex/engine.rb +13 -13
- data/lib/view_component_reflex/state_adapter/memory.rb +25 -0
- data/lib/view_component_reflex/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb949fc8de60d18d54d72195cd04947ba24ef73db4091b2ddd0c2992287df7d0
|
4
|
+
data.tar.gz: c474384a6b9c073ba4efbf924067113971e67c4e8bdc0fbfa6462471ecf95b6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0f4a365d380e55ba8deb5f567f35fa81b2aa8ab108cd2aca4f6e97041139e8e53f446f30db3ddcea0ee0fcb08e62b2f98feef14b83f5810c54ce705a6564716
|
7
|
+
data.tar.gz: df46044a3c7bddc9ab204ddb052fce04f0cecf190428043a3aa4ff2fb5a1b86d7d4e9524fa509ecbea51991641f8b4da9b8eaed2b1f4ede565c6cdb922a07724
|
data/README.md
CHANGED
@@ -70,8 +70,8 @@ end
|
|
70
70
|
```
|
71
71
|
|
72
72
|
### omitted_from_state
|
73
|
-
Return an array of instance variables you want to omit from state.
|
74
|
-
|
73
|
+
Return an array of instance variables you want to omit from state. Only really useful if you're using the session state
|
74
|
+
adapter, and you have an instance variable that can't be serialized.
|
75
75
|
|
76
76
|
```ruby
|
77
77
|
def omitted_from_state
|
@@ -181,6 +181,11 @@ end
|
|
181
181
|
<% end
|
182
182
|
```
|
183
183
|
|
184
|
+
## State
|
185
|
+
|
186
|
+
By default, view_component_reflex stores component state in memory. You can optionally set the state adapter
|
187
|
+
to use the session by changing `config.state_adapter` to `ViewComponentReflex::StateAdapter::Session`
|
188
|
+
|
184
189
|
## Custom State Adapters
|
185
190
|
|
186
191
|
ViewComponentReflex uses session for its state by default. To change this, add
|
@@ -4,21 +4,53 @@ module ViewComponentReflex
|
|
4
4
|
def init_stimulus_reflex
|
5
5
|
klass = self
|
6
6
|
@stimulus_reflex ||= Object.const_set(name + "Reflex", Class.new(StimulusReflex::Reflex) {
|
7
|
-
def refresh!(
|
7
|
+
def refresh!(*selectors)
|
8
8
|
save_state
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
|
10
|
+
# If the component has instance variables omitted from state,
|
11
|
+
# we can't render it to string from here because those instance
|
12
|
+
# variables will be missing. In that case, set the selectors to the
|
13
|
+
# default selector and manually morph the page
|
14
|
+
if selectors.empty? && !component.can_render_to_string?
|
15
|
+
selectors.push selector
|
16
|
+
end
|
17
|
+
|
18
|
+
# If we're just updating the component itself, we can
|
19
|
+
# directly render it instead of rendering the entire page again
|
20
|
+
if selectors.empty?
|
21
|
+
refresh_component!
|
22
|
+
else
|
23
|
+
@channel.send :render_page_and_broadcast_morph, self, selectors, {
|
24
|
+
"dataset" => element.dataset.to_h,
|
25
|
+
"args" => [],
|
26
|
+
"attrs" => element.attributes.to_h,
|
27
|
+
"selectors" => ["body"],
|
28
|
+
"target" => "#{self.class.name}##{method_name}",
|
29
|
+
"url" => request.url,
|
30
|
+
"permanent_attribute_name" => permanent_attribute_name
|
31
|
+
}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def refresh_component!
|
36
|
+
# The component can't figure out the key when we render from here
|
37
|
+
# Luckily we already know the key, so we can manually override it
|
38
|
+
component.tap do |k|
|
39
|
+
k.define_singleton_method(:key) do
|
40
|
+
element.dataset[:key]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
html = controller.render_component_to_string(component)
|
44
|
+
document = Nokogiri::HTML(html)
|
45
|
+
morph selector, document.css("#{selector} > *").to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
def selector
|
49
|
+
"[data-controller~=\"#{stimulus_controller}\"][data-key=\"#{element.dataset[:key]}\"]"
|
18
50
|
end
|
19
51
|
|
20
52
|
def refresh_all!
|
21
|
-
|
53
|
+
morph :body, render_page(self)
|
22
54
|
end
|
23
55
|
|
24
56
|
# SR's delegate_call_to_reflex in channel.rb
|
@@ -32,11 +64,6 @@ module ViewComponentReflex
|
|
32
64
|
!!name.to_proc
|
33
65
|
end
|
34
66
|
|
35
|
-
before_reflex do |a|
|
36
|
-
a.send a.method_name
|
37
|
-
throw :abort
|
38
|
-
end
|
39
|
-
|
40
67
|
def method_missing(name, *args)
|
41
68
|
super unless respond_to_missing?(name)
|
42
69
|
state.each do |k, v|
|
@@ -85,7 +112,7 @@ module ViewComponentReflex
|
|
85
112
|
|
86
113
|
def save_state
|
87
114
|
new_state = {}
|
88
|
-
component.
|
115
|
+
component.safe_instance_variables.each do |k|
|
89
116
|
new_state[k] = component.instance_variable_get(k)
|
90
117
|
end
|
91
118
|
set_state(new_state)
|
@@ -102,6 +129,10 @@ module ViewComponentReflex
|
|
102
129
|
helpers.controller.instance_variable_get(:@stimulus_reflex)
|
103
130
|
end
|
104
131
|
|
132
|
+
def can_render_to_string?
|
133
|
+
omitted_from_state.empty?
|
134
|
+
end
|
135
|
+
|
105
136
|
def component_controller(opts_or_tag = :div, opts = {}, &blk)
|
106
137
|
self.class.init_stimulus_reflex
|
107
138
|
init_key
|
@@ -165,18 +196,10 @@ module ViewComponentReflex
|
|
165
196
|
|
166
197
|
def key
|
167
198
|
# initialize session state
|
168
|
-
if !stimulus_reflex? ||
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
blacklist = [
|
173
|
-
:@view_context, :@lookup_context, :@view_renderer, :@view_flow,
|
174
|
-
:@virtual_path, :@variant, :@current_template, :@output_buffer, :@key,
|
175
|
-
:@helpers, :@controller, :@request, :@content
|
176
|
-
]
|
177
|
-
instance_variables.reject { |k| blacklist.include?(k) }.each do |k|
|
178
|
-
new_state[k] = instance_variable_get(k) unless omitted_from_state.include?(k)
|
179
|
-
end
|
199
|
+
if !stimulus_reflex? || ViewComponentReflex::Engine.state_adapter.state(request, @key).empty?
|
200
|
+
|
201
|
+
new_state = create_safe_state
|
202
|
+
|
180
203
|
ViewComponentReflex::Engine.state_adapter.store_state(request, @key, new_state)
|
181
204
|
ViewComponentReflex::Engine.state_adapter.store_state(request, "#{@key}_initial", new_state)
|
182
205
|
else
|
@@ -190,8 +213,30 @@ module ViewComponentReflex
|
|
190
213
|
@key
|
191
214
|
end
|
192
215
|
|
216
|
+
def safe_instance_variables
|
217
|
+
instance_variables - unsafe_instance_variables
|
218
|
+
end
|
219
|
+
|
193
220
|
private
|
194
221
|
|
222
|
+
def unsafe_instance_variables
|
223
|
+
[
|
224
|
+
:@view_context, :@lookup_context, :@view_renderer, :@view_flow,
|
225
|
+
:@virtual_path, :@variant, :@current_template, :@output_buffer, :@key,
|
226
|
+
:@helpers, :@controller, :@request, :@content, :@tag_builder
|
227
|
+
]
|
228
|
+
end
|
229
|
+
|
230
|
+
def create_safe_state
|
231
|
+
new_state = {}
|
232
|
+
|
233
|
+
# this will almost certainly break
|
234
|
+
safe_instance_variables.each do |k|
|
235
|
+
new_state[k] = instance_variable_get(k) unless omitted_from_state.include?(k)
|
236
|
+
end
|
237
|
+
new_state
|
238
|
+
end
|
239
|
+
|
195
240
|
def merge_data_attributes(options, attributes)
|
196
241
|
data = options[:data]
|
197
242
|
if data.nil?
|
@@ -1,7 +1,8 @@
|
|
1
|
-
require "view_component_reflex/state_adapter/session"
|
2
|
-
require "view_component_reflex/
|
3
|
-
require
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
require "view_component_reflex/state_adapter/session"
|
2
|
+
require "view_component_reflex/state_adapter/memory"
|
3
|
+
require "view_component_reflex/engine"
|
4
|
+
require 'stimulus_reflex'
|
5
|
+
|
6
|
+
module ViewComponentReflex
|
7
|
+
# Your code goes here...
|
8
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
module ViewComponentReflex
|
2
|
-
class Engine < ::Rails::Engine
|
3
|
-
class << self
|
4
|
-
mattr_accessor :state_adapter
|
5
|
-
|
6
|
-
self.state_adapter = StateAdapter::
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.configure
|
10
|
-
yield self if block_given?
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
1
|
+
module ViewComponentReflex
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
class << self
|
4
|
+
mattr_accessor :state_adapter
|
5
|
+
|
6
|
+
self.state_adapter = StateAdapter::Memory
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.configure
|
10
|
+
yield self if block_given?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE = {}
|
2
|
+
module ViewComponentReflex
|
3
|
+
module StateAdapter
|
4
|
+
class Memory
|
5
|
+
def self.state(request, key)
|
6
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE[request.session.id.to_s] ||= {}
|
7
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE[request.session.id.to_s][key] ||= {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.set_state(request, _, key, new_state)
|
11
|
+
new_state.each do |k, v|
|
12
|
+
state(request, key)[k] = v
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.store_state(request, key, new_state = {})
|
17
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE[request.session.id.to_s] ||= {}
|
18
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE[request.session.id.to_s][key] ||= {}
|
19
|
+
new_state.each do |k, v|
|
20
|
+
VIEW_COMPONENT_REFLEX_MEMORY_STATE[request.session.id.to_s][key][k] = v
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
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: 1.
|
4
|
+
version: 1.7.0
|
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-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- app/components/view_component_reflex/component.rb
|
72
72
|
- lib/view_component_reflex.rb
|
73
73
|
- lib/view_component_reflex/engine.rb
|
74
|
+
- lib/view_component_reflex/state_adapter/memory.rb
|
74
75
|
- lib/view_component_reflex/state_adapter/session.rb
|
75
76
|
- lib/view_component_reflex/version.rb
|
76
77
|
homepage: https://github.com/joshleblanc/view_component_reflex
|