view_component_reflex 2.3.10 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +32 -3
- data/app/components/view_component_reflex/component.rb +20 -7
- data/lib/view_component_reflex.rb +1 -0
- data/lib/view_component_reflex/reflex.rb +1 -1
- data/lib/view_component_reflex/state_adapter/memory.rb +4 -0
- data/lib/view_component_reflex/state_adapter/redis.rb +74 -0
- data/lib/view_component_reflex/state_adapter/session.rb +4 -0
- data/lib/view_component_reflex/version.rb +1 -1
- metadata +11 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48be01529611392c673d2ca154ba25657bde6564cfb9238c78debea251f3aa11
|
4
|
+
data.tar.gz: 41d40953951fbd6d26fa4044ad41e1ca6b5b2a969439404d78f755853ea1acca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6b645acacb1f3716b05cf134225255096aa80ef47a131949d79f0cbfec69a9623c6f26d061d381f6637ff26501eeaeabdfe17c52e7cb2be027eda0e5eba91ec
|
7
|
+
data.tar.gz: 9d714a2889b6d4f100cd816f6068699e86966807bf529353b9ab2699738d649a5169116926e75fd5690a2cbb7a0583574cf164b52518b4cff29e86745a38d803
|
data/README.md
CHANGED
@@ -161,7 +161,7 @@ By default, VCR will re-render your component after it executes your method. `pr
|
|
161
161
|
```ruby
|
162
162
|
def my_method
|
163
163
|
prevent_refresh!
|
164
|
-
@foo =
|
164
|
+
@foo = :bar
|
165
165
|
end # the rendered page will not reflect this change
|
166
166
|
```
|
167
167
|
|
@@ -193,6 +193,19 @@ You *must* wrap your component in this for everything to work properly.
|
|
193
193
|
<% end %>
|
194
194
|
```
|
195
195
|
|
196
|
+
### after_state_initialized(parameters_changed)
|
197
|
+
|
198
|
+
This is called after the state has been inserted in the component. You can use this to run conditional functions after
|
199
|
+
some parameter has superseeded whatever's in state
|
200
|
+
|
201
|
+
```
|
202
|
+
def after_state_initialized(parameters_changed)
|
203
|
+
if parameters_changed.include?(:@filter)
|
204
|
+
calculate_visible_rows
|
205
|
+
end
|
206
|
+
end
|
207
|
+
```
|
208
|
+
|
196
209
|
## Custom reflex base class
|
197
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` method.
|
198
211
|
The parent class must inherit ViewComponentReflex::Reflex, and will throw an error if it does not.
|
@@ -245,8 +258,8 @@ end
|
|
245
258
|
|
246
259
|
## State
|
247
260
|
|
248
|
-
By default, view_component_reflex stores component state in
|
249
|
-
to use the
|
261
|
+
By default (since version `2.3.2`), view_component_reflex stores component state in session. You can optionally set the state adapter
|
262
|
+
to use the memory by changing `config.state_adapter` to `ViewComponentReflex::StateAdapter::Memory`.
|
250
263
|
|
251
264
|
## Custom State Adapters
|
252
265
|
|
@@ -259,6 +272,22 @@ ViewComponentReflex::Engine.configure do |config|
|
|
259
272
|
end
|
260
273
|
```
|
261
274
|
|
275
|
+
|
276
|
+
## Existing Fast Redis based State Adapter
|
277
|
+
|
278
|
+
This adapter uses hmset and hgetall to reduce the number of operations.
|
279
|
+
This is the recommended adapter if you are using AnyCable.
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
ViewComponentReflex::Engine.configure do |config|
|
283
|
+
config.state_adapter = ViewComponentReflex::StateAdapter::Redis.new(
|
284
|
+
redis_opts: {
|
285
|
+
url: "redis://localhost:6379/1", driver: :hiredis
|
286
|
+
},
|
287
|
+
ttl: 3600)
|
288
|
+
end
|
289
|
+
```
|
290
|
+
|
262
291
|
`YourAdapter` should implement
|
263
292
|
|
264
293
|
```ruby
|
@@ -139,33 +139,46 @@ module ViewComponentReflex
|
|
139
139
|
[]
|
140
140
|
end
|
141
141
|
|
142
|
+
def after_state_initialized(parameters_changed)
|
143
|
+
# called after state component has been hydrated
|
144
|
+
end
|
145
|
+
|
142
146
|
# def receive_params(old_state, params)
|
143
147
|
# # no op
|
144
148
|
# end
|
145
149
|
|
146
150
|
def key
|
151
|
+
adapter = ViewComponentReflex::Engine.state_adapter
|
152
|
+
|
147
153
|
# initialize session state
|
148
|
-
if !stimulus_reflex? ||
|
154
|
+
if !stimulus_reflex? || adapter.state(request, @key).empty?
|
149
155
|
|
150
156
|
new_state = create_safe_state
|
151
157
|
|
152
|
-
|
153
|
-
|
158
|
+
adapter.wrap_write_async do
|
159
|
+
adapter.store_state(request, @key, new_state)
|
160
|
+
adapter.store_state(request, "#{@key}_initial", new_state)
|
161
|
+
end
|
154
162
|
elsif !@initialized_state
|
155
|
-
initial_state =
|
163
|
+
initial_state = adapter.state(request, "#{@key}_initial")
|
156
164
|
|
157
165
|
# incoming_params = safe_instance_variables.each_with_object({}) { |var, obj| obj[var] = instance_variable_get(var) }
|
158
166
|
# receive_params(ViewComponentReflex::Engine.state_adapter.state(request, @key), incoming_params)
|
159
167
|
|
160
|
-
|
168
|
+
parameters_changed = []
|
169
|
+
adapter.state(request, @key).each do |k, v|
|
161
170
|
instance_value = instance_variable_get(k)
|
162
171
|
if permit_parameter?(initial_state[k], instance_value)
|
163
|
-
|
164
|
-
|
172
|
+
parameters_changed << k
|
173
|
+
adapter.wrap_write_async do
|
174
|
+
adapter.set_state(request, controller, "#{@key}_initial", {k => instance_value})
|
175
|
+
adapter.set_state(request, controller, @key, {k => instance_value})
|
176
|
+
end
|
165
177
|
else
|
166
178
|
instance_variable_set(k, v)
|
167
179
|
end
|
168
180
|
end
|
181
|
+
after_state_initialized(parameters_changed)
|
169
182
|
@initialized_state = true
|
170
183
|
end
|
171
184
|
@key
|
@@ -2,6 +2,7 @@ require "stimulus_reflex"
|
|
2
2
|
require 'view_component_reflex/reflex_factory'
|
3
3
|
require "view_component_reflex/state_adapter/session"
|
4
4
|
require "view_component_reflex/state_adapter/memory"
|
5
|
+
require "view_component_reflex/state_adapter/redis"
|
5
6
|
require "view_component_reflex/reflex"
|
6
7
|
require "view_component_reflex/engine"
|
7
8
|
|
@@ -119,7 +119,7 @@ module ViewComponentReflex
|
|
119
119
|
return @component if @component
|
120
120
|
@component = component_class.allocate
|
121
121
|
reflex = self
|
122
|
-
exposed_methods = [:params, :request, :element, :refresh!, :refresh_all!, :stimulus_controller, :session, :prevent_refresh!, :selector, :stimulate]
|
122
|
+
exposed_methods = [:params, :request, :connection, :element, :refresh!, :refresh_all!, :stimulus_controller, :session, :prevent_refresh!, :selector, :stimulate]
|
123
123
|
exposed_methods.each do |meth|
|
124
124
|
@component.define_singleton_method(meth) do |*a|
|
125
125
|
reflex.send(meth, *a)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# A redis based adapter for component_reflex
|
2
|
+
#
|
3
|
+
# ViewComponentReflex::Engine.configure do |config|
|
4
|
+
# config.state_adapter = ViewComponentReflex::StateAdapter::Redis.new(
|
5
|
+
# redis_opts: {
|
6
|
+
# url: "redis://localhost:6379/1", driver: :hiredis
|
7
|
+
# },
|
8
|
+
# ttl: 3600)
|
9
|
+
# end
|
10
|
+
|
11
|
+
module ViewComponentReflex
|
12
|
+
module StateAdapter
|
13
|
+
class Redis
|
14
|
+
attr_reader :client, :ttl
|
15
|
+
|
16
|
+
def initialize(redis_opts:, ttl: 3600)
|
17
|
+
@client = ::Redis.new(redis_opts)
|
18
|
+
@ttl = ttl
|
19
|
+
end
|
20
|
+
|
21
|
+
def state(request, key)
|
22
|
+
cache_key = get_key(request, key)
|
23
|
+
value = client.hgetall(cache_key)
|
24
|
+
|
25
|
+
return {} if value.nil?
|
26
|
+
|
27
|
+
value.map do |k, v|
|
28
|
+
[k, Marshal.load(v)]
|
29
|
+
end.to_h
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_state(request, _, key, new_state)
|
33
|
+
cache_key = get_key(request, key)
|
34
|
+
save_to_redis(cache_key, new_state)
|
35
|
+
end
|
36
|
+
|
37
|
+
def store_state(request, key, new_state = {})
|
38
|
+
cache_key = get_key(request, key)
|
39
|
+
optimized_store_to_redis(cache_key, new_state, request)
|
40
|
+
end
|
41
|
+
|
42
|
+
def wrap_write_async
|
43
|
+
client.pipelined do
|
44
|
+
yield
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# Reduce number of calls coming from #store_state to save Redis
|
51
|
+
# when it's first rendered
|
52
|
+
def optimized_store_to_redis(cache_key, new_state, request)
|
53
|
+
request.env["CACHE_REDIS_REFLEX"] ||= []
|
54
|
+
return if request.env["CACHE_REDIS_REFLEX"].include?(cache_key)
|
55
|
+
request.env["CACHE_REDIS_REFLEX"].push(cache_key)
|
56
|
+
|
57
|
+
save_to_redis(cache_key, new_state)
|
58
|
+
end
|
59
|
+
|
60
|
+
def save_to_redis(cache_key, new_state)
|
61
|
+
new_state_json = new_state.map do |k, v|
|
62
|
+
[k, Marshal.dump(v)]
|
63
|
+
end
|
64
|
+
|
65
|
+
client.hmset(cache_key, new_state_json.flatten)
|
66
|
+
client.expire(cache_key, ttl)
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_key(request, key)
|
70
|
+
"#{request.session.id.to_s}_#{key}_session_reflex_redis"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: view_component_reflex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.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-10-
|
11
|
+
date: 2020-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 6.0.3
|
20
17
|
- - ">="
|
21
18
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
19
|
+
version: '5.2'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '7.0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- - "~>"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 6.0.3
|
30
27
|
- - ">="
|
31
28
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
29
|
+
version: '5.2'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '7.0'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: stimulus_reflex
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,6 +74,7 @@ files:
|
|
74
74
|
- lib/view_component_reflex/reflex.rb
|
75
75
|
- lib/view_component_reflex/reflex_factory.rb
|
76
76
|
- lib/view_component_reflex/state_adapter/memory.rb
|
77
|
+
- lib/view_component_reflex/state_adapter/redis.rb
|
77
78
|
- lib/view_component_reflex/state_adapter/session.rb
|
78
79
|
- lib/view_component_reflex/version.rb
|
79
80
|
homepage: https://github.com/joshleblanc/view_component_reflex
|