hyper-store 0.99.6 → 1.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/hyper-store.gemspec +11 -6
- data/lib/hyper-store.rb +21 -16
- data/lib/hyperstack/internal/store/class_methods.rb +36 -0
- data/lib/hyperstack/internal/store/dispatch_receiver.rb +41 -0
- data/lib/hyperstack/internal/store/instance_methods.rb +45 -0
- data/lib/hyperstack/internal/store/mutator_wrapper.rb +84 -0
- data/lib/hyperstack/internal/store/observable.rb +33 -0
- data/lib/hyperstack/internal/store/state.rb +174 -0
- data/lib/hyperstack/internal/store/state_wrapper.rb +116 -0
- data/lib/hyperstack/internal/store/state_wrapper/argument_validator.rb +93 -0
- data/lib/hyperstack/legacy/store.rb +23 -0
- data/lib/hyperstack/legacy/store/version.rb +7 -0
- metadata +81 -28
- data/DOCS.md +0 -312
- data/README.md +0 -70
- data/lib/hyper-store/class_methods.rb +0 -32
- data/lib/hyper-store/dispatch_receiver.rb +0 -38
- data/lib/hyper-store/instance_methods.rb +0 -40
- data/lib/hyper-store/mutator_wrapper.rb +0 -71
- data/lib/hyper-store/state_wrapper.rb +0 -107
- data/lib/hyper-store/state_wrapper/argument_validator.rb +0 -91
- data/lib/hyper-store/version.rb +0 -3
- data/lib/hyperloop/application/boot.rb +0 -34
- data/lib/hyperloop/store.rb +0 -12
- data/lib/hyperloop/store/mixin.rb +0 -21
- data/lib/react/observable.rb +0 -29
- data/lib/react/state.rb +0 -157
@@ -0,0 +1,116 @@
|
|
1
|
+
module Hyperstack
|
2
|
+
module Internal
|
3
|
+
module Store
|
4
|
+
class StateWrapper < BaseStoreClass
|
5
|
+
extend ArgumentValidator
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_reader :instance_state_wrapper, :class_state_wrapper,
|
9
|
+
:instance_mutator_wrapper, :class_mutator_wrapper,
|
10
|
+
:wrappers
|
11
|
+
|
12
|
+
def inherited(subclass)
|
13
|
+
subclass.add_class_instance_vars(subclass) if self == StateWrapper
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_class_instance_vars(subclass)
|
17
|
+
@shared_state_wrapper = subclass
|
18
|
+
@instance_state_wrapper = Class.new(@shared_state_wrapper)
|
19
|
+
@class_state_wrapper = Class.new(@shared_state_wrapper)
|
20
|
+
|
21
|
+
@shared_mutator_wrapper = Class.new(MutatorWrapper)
|
22
|
+
@instance_mutator_wrapper = Class.new(@shared_mutator_wrapper)
|
23
|
+
@class_mutator_wrapper = Class.new(@shared_mutator_wrapper)
|
24
|
+
|
25
|
+
@wrappers = [@instance_state_wrapper, @instance_mutator_wrapper,
|
26
|
+
@class_state_wrapper, @class_mutator_wrapper]
|
27
|
+
end
|
28
|
+
|
29
|
+
def define_state_methods(klass, *args, &block)
|
30
|
+
return self if args.empty?
|
31
|
+
|
32
|
+
name, opts = validate_args!(klass, *args, &block)
|
33
|
+
|
34
|
+
add_readers(klass, name, opts)
|
35
|
+
klass.singleton_class.state.add_error_methods(name, opts)
|
36
|
+
klass.singleton_class.state.add_methods(klass, name, opts)
|
37
|
+
klass.singleton_class.state.remove_methods(name, opts)
|
38
|
+
klass.send(:"__#{opts[:scope]}_states") << [name, opts]
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_readers(klass, name, opts)
|
42
|
+
return unless opts[:reader]
|
43
|
+
|
44
|
+
if [:instance, :shared].include?(opts[:scope])
|
45
|
+
klass.class_eval do
|
46
|
+
define_method(:"#{opts[:reader]}") { state.__send__(:"#{name}") }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if [:class, :shared].include?(opts[:scope])
|
51
|
+
klass.define_singleton_method(:"#{opts[:reader]}") { state.__send__(:"#{name}") }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_error_methods(name, opts)
|
56
|
+
return if opts[:scope] == :shared
|
57
|
+
|
58
|
+
[@shared_state_wrapper, @shared_mutator_wrapper].each do |klass|
|
59
|
+
klass.define_singleton_method(:"#{name}") do
|
60
|
+
'nope!'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_methods(klass, name, opts)
|
66
|
+
instance_variable_get("@#{opts[:scope]}_state_wrapper").add_method(klass, name, opts)
|
67
|
+
instance_variable_get("@#{opts[:scope]}_mutator_wrapper").add_method(klass, name, opts)
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_method(klass, method_name, opts = {})
|
71
|
+
define_method(:"#{method_name}") do
|
72
|
+
from = opts[:scope] == :shared ? klass.state.__from__ : @__from__
|
73
|
+
from.init_store if from.respond_to? :init_store
|
74
|
+
State.get_state(from, method_name.to_s)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def remove_methods(name, opts)
|
79
|
+
return unless opts[:scope] == :shared
|
80
|
+
|
81
|
+
wrappers.each do |wrapper|
|
82
|
+
wrapper.send(:remove_method, :"#{name}") if wrapper.respond_to?(:"#{name}")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def default_scope(klass)
|
87
|
+
if self == klass.singleton_class.__state_wrapper.class_state_wrapper
|
88
|
+
:instance
|
89
|
+
else
|
90
|
+
:class
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
attr_accessor :__from__
|
96
|
+
|
97
|
+
def self.new(from)
|
98
|
+
instance = allocate
|
99
|
+
instance.__from__ = from
|
100
|
+
instance
|
101
|
+
end
|
102
|
+
|
103
|
+
def [](name)
|
104
|
+
__send__(name)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Any method_missing call will create a state and accessor with that name
|
108
|
+
def method_missing(name, *args, &block) # rubocop:disable Style/MethodMissing
|
109
|
+
$method_missing = [name, *args]
|
110
|
+
(class << self; self end).add_method(nil, name) #(class << self; self end).superclass.add_method(nil, name)
|
111
|
+
__send__(name, *args, &block)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Hyperstack
|
2
|
+
module Internal
|
3
|
+
module Store
|
4
|
+
class StateWrapper < BaseStoreClass
|
5
|
+
module ArgumentValidator
|
6
|
+
def validate_args!(klass, *args, &block)
|
7
|
+
name, initial_value, opts = parse_arguments(*args, &block)
|
8
|
+
|
9
|
+
opts[:scope] ||= default_scope(klass)
|
10
|
+
opts[:initializer] = validate_initializer(initial_value, klass, opts)
|
11
|
+
opts[:block] = block if block
|
12
|
+
|
13
|
+
if opts[:reader]
|
14
|
+
opts[:reader] = opts[:reader] == true ? name : opts[:reader]
|
15
|
+
end
|
16
|
+
|
17
|
+
[name, opts]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def invalid_option(message)
|
23
|
+
raise Legacy::Store::InvalidOptionError, message
|
24
|
+
end
|
25
|
+
|
26
|
+
# Parses the arguments given to get the name, initial_value (if any), and options
|
27
|
+
def parse_arguments(*args)
|
28
|
+
# If the only argument is a hash, the first key => value is name => inital_value
|
29
|
+
if args.first.is_a?(Hash)
|
30
|
+
# If the first key passed in is not the name, raise an error
|
31
|
+
if [:reader, :initializer, :scope].include?(args.first.keys.first.to_sym)
|
32
|
+
message = 'The name of the state must be specified first as '\
|
33
|
+
"either 'state :name' or 'state name: nil'"
|
34
|
+
invalid_option(message)
|
35
|
+
end
|
36
|
+
|
37
|
+
name, initial_value = args[0].shift
|
38
|
+
# Otherwise just the name is passed in by itself first
|
39
|
+
else
|
40
|
+
name = args.shift
|
41
|
+
end
|
42
|
+
|
43
|
+
# [name, initial_value (can be nil), args (if nil then return an empty hash)]
|
44
|
+
[name, initial_value, args[0] || {}]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Converts the initialize option to a Proc
|
48
|
+
def validate_initializer(initial_value, klass, opts) # rubocop:disable Metrics/MethodLength
|
49
|
+
# If we pass in the name as a hash with a value ex: state foo: :bar,
|
50
|
+
# we just put that value inside a Proc and return that
|
51
|
+
if initial_value != nil
|
52
|
+
dup_or_return_intial_value(initial_value)
|
53
|
+
# If we pass in the initialize option
|
54
|
+
elsif opts[:initializer]
|
55
|
+
# If it's a Symbol we convert to to a Proc that calls the method on the instance
|
56
|
+
if [Symbol, String].include?(opts[:initializer].class)
|
57
|
+
method_name = opts[:initializer]
|
58
|
+
if [:class, :shared].include?(opts[:scope])
|
59
|
+
-> { klass.send(:"#{method_name}") }
|
60
|
+
else
|
61
|
+
->(instance) { instance.send(:"#{method_name}") }
|
62
|
+
end
|
63
|
+
# If it is already a Proc we do nothing and just return what was given
|
64
|
+
elsif opts[:initializer].is_a?(Proc)
|
65
|
+
opts[:initializer]
|
66
|
+
# If it's not a Proc or a String we raise an error and return an empty Proc
|
67
|
+
else
|
68
|
+
invalid_option("'state' option 'initialize' must either be a Symbol or a Proc")
|
69
|
+
-> {}
|
70
|
+
end
|
71
|
+
# Otherwise if it's not specified we just return an empty Proc
|
72
|
+
else
|
73
|
+
-> {}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Dup the initial value if possible, otherwise just return it
|
78
|
+
# Ruby has no nice way of doing this...
|
79
|
+
def dup_or_return_intial_value(value)
|
80
|
+
value =
|
81
|
+
begin
|
82
|
+
value.dup
|
83
|
+
rescue
|
84
|
+
value
|
85
|
+
end
|
86
|
+
|
87
|
+
-> { value }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Hyperstack
|
2
|
+
module Legacy
|
3
|
+
module Store
|
4
|
+
class InvalidOptionError < StandardError; end
|
5
|
+
class InvalidOperationError < StandardError; end
|
6
|
+
class << self
|
7
|
+
def included(base)
|
8
|
+
base.include(Hyperstack::Internal::Store::InstanceMethods)
|
9
|
+
base.extend(Hyperstack::Internal::Store::ClassMethods)
|
10
|
+
base.extend(Hyperstack::Internal::Store::DispatchReceiver)
|
11
|
+
|
12
|
+
base.singleton_class.define_singleton_method(:__state_wrapper) do
|
13
|
+
@__state_wrapper ||= Class.new(Hyperstack::Internal::Store::StateWrapper)
|
14
|
+
end
|
15
|
+
|
16
|
+
base.singleton_class.define_singleton_method(:state) do |*args, &block|
|
17
|
+
__state_wrapper.define_state_methods(base, *args, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hyper-store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.alpha1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mitch VanDuyn
|
@@ -10,22 +10,36 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2018-11-12 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: hyperstack-config
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
19
|
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 1.0.alpha1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - '='
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 0.
|
28
|
+
version: 1.0.alpha1
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: hyper-state
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - '='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 1.0.alpha1
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - '='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.0.alpha1
|
29
43
|
- !ruby/object:Gem::Dependency
|
30
44
|
name: opal
|
31
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,28 +94,28 @@ dependencies:
|
|
80
94
|
requirements:
|
81
95
|
- - '='
|
82
96
|
- !ruby/object:Gem::Version
|
83
|
-
version: 0.
|
97
|
+
version: 1.0.alpha1
|
84
98
|
type: :development
|
85
99
|
prerelease: false
|
86
100
|
version_requirements: !ruby/object:Gem::Requirement
|
87
101
|
requirements:
|
88
102
|
- - '='
|
89
103
|
- !ruby/object:Gem::Version
|
90
|
-
version: 0.
|
104
|
+
version: 1.0.alpha1
|
91
105
|
- !ruby/object:Gem::Dependency
|
92
106
|
name: hyper-spec
|
93
107
|
requirement: !ruby/object:Gem::Requirement
|
94
108
|
requirements:
|
95
109
|
- - '='
|
96
110
|
- !ruby/object:Gem::Version
|
97
|
-
version: 0.
|
111
|
+
version: 1.0.alpha1
|
98
112
|
type: :development
|
99
113
|
prerelease: false
|
100
114
|
version_requirements: !ruby/object:Gem::Requirement
|
101
115
|
requirements:
|
102
116
|
- - '='
|
103
117
|
- !ruby/object:Gem::Version
|
104
|
-
version: 0.
|
118
|
+
version: 1.0.alpha1
|
105
119
|
- !ruby/object:Gem::Dependency
|
106
120
|
name: listen
|
107
121
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,14 +136,14 @@ dependencies:
|
|
122
136
|
requirements:
|
123
137
|
- - "~>"
|
124
138
|
- !ruby/object:Gem::Version
|
125
|
-
version: 0.
|
139
|
+
version: 0.1.15
|
126
140
|
type: :development
|
127
141
|
prerelease: false
|
128
142
|
version_requirements: !ruby/object:Gem::Requirement
|
129
143
|
requirements:
|
130
144
|
- - "~>"
|
131
145
|
- !ruby/object:Gem::Version
|
132
|
-
version: 0.
|
146
|
+
version: 0.1.15
|
133
147
|
- !ruby/object:Gem::Dependency
|
134
148
|
name: opal-browser
|
135
149
|
requirement: !ruby/object:Gem::Requirement
|
@@ -172,6 +186,20 @@ dependencies:
|
|
172
186
|
- - ">="
|
173
187
|
- !ruby/object:Gem::Version
|
174
188
|
version: '0'
|
189
|
+
- !ruby/object:Gem::Dependency
|
190
|
+
name: pry-rescue
|
191
|
+
requirement: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '0'
|
196
|
+
type: :development
|
197
|
+
prerelease: false
|
198
|
+
version_requirements: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - ">="
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '0'
|
175
203
|
- !ruby/object:Gem::Dependency
|
176
204
|
name: puma
|
177
205
|
requirement: !ruby/object:Gem::Requirement
|
@@ -248,6 +276,20 @@ dependencies:
|
|
248
276
|
- - "~>"
|
249
277
|
- !ruby/object:Gem::Version
|
250
278
|
version: 3.7.0
|
279
|
+
- !ruby/object:Gem::Dependency
|
280
|
+
name: rspec-rails
|
281
|
+
requirement: !ruby/object:Gem::Requirement
|
282
|
+
requirements:
|
283
|
+
- - ">="
|
284
|
+
- !ruby/object:Gem::Version
|
285
|
+
version: '0'
|
286
|
+
type: :development
|
287
|
+
prerelease: false
|
288
|
+
version_requirements: !ruby/object:Gem::Requirement
|
289
|
+
requirements:
|
290
|
+
- - ">="
|
291
|
+
- !ruby/object:Gem::Version
|
292
|
+
version: '0'
|
251
293
|
- !ruby/object:Gem::Dependency
|
252
294
|
name: rspec-steps
|
253
295
|
requirement: !ruby/object:Gem::Requirement
|
@@ -290,6 +332,20 @@ dependencies:
|
|
290
332
|
- - ">="
|
291
333
|
- !ruby/object:Gem::Version
|
292
334
|
version: '0'
|
335
|
+
- !ruby/object:Gem::Dependency
|
336
|
+
name: timecop
|
337
|
+
requirement: !ruby/object:Gem::Requirement
|
338
|
+
requirements:
|
339
|
+
- - "~>"
|
340
|
+
- !ruby/object:Gem::Version
|
341
|
+
version: 0.8.1
|
342
|
+
type: :development
|
343
|
+
prerelease: false
|
344
|
+
version_requirements: !ruby/object:Gem::Requirement
|
345
|
+
requirements:
|
346
|
+
- - "~>"
|
347
|
+
- !ruby/object:Gem::Version
|
348
|
+
version: 0.8.1
|
293
349
|
description:
|
294
350
|
email:
|
295
351
|
- mitch@catprint.com
|
@@ -300,26 +356,22 @@ extra_rdoc_files: []
|
|
300
356
|
files:
|
301
357
|
- ".gitignore"
|
302
358
|
- ".travis.yml"
|
303
|
-
- DOCS.md
|
304
359
|
- Gemfile
|
305
|
-
- README.md
|
306
360
|
- Rakefile
|
307
361
|
- bin/console
|
308
362
|
- bin/setup
|
309
363
|
- hyper-store.gemspec
|
310
364
|
- lib/hyper-store.rb
|
311
|
-
- lib/
|
312
|
-
- lib/
|
313
|
-
- lib/
|
314
|
-
- lib/
|
315
|
-
- lib/
|
316
|
-
- lib/
|
317
|
-
- lib/
|
318
|
-
- lib/
|
319
|
-
- lib/
|
320
|
-
- lib/
|
321
|
-
- lib/react/observable.rb
|
322
|
-
- lib/react/state.rb
|
365
|
+
- lib/hyperstack/internal/store/class_methods.rb
|
366
|
+
- lib/hyperstack/internal/store/dispatch_receiver.rb
|
367
|
+
- lib/hyperstack/internal/store/instance_methods.rb
|
368
|
+
- lib/hyperstack/internal/store/mutator_wrapper.rb
|
369
|
+
- lib/hyperstack/internal/store/observable.rb
|
370
|
+
- lib/hyperstack/internal/store/state.rb
|
371
|
+
- lib/hyperstack/internal/store/state_wrapper.rb
|
372
|
+
- lib/hyperstack/internal/store/state_wrapper/argument_validator.rb
|
373
|
+
- lib/hyperstack/legacy/store.rb
|
374
|
+
- lib/hyperstack/legacy/store/version.rb
|
323
375
|
homepage: https://ruby-hyperloop.org
|
324
376
|
licenses:
|
325
377
|
- MIT
|
@@ -335,11 +387,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
335
387
|
version: '0'
|
336
388
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
337
389
|
requirements:
|
338
|
-
- - "
|
390
|
+
- - ">"
|
339
391
|
- !ruby/object:Gem::Version
|
340
|
-
version:
|
392
|
+
version: 1.3.1
|
341
393
|
requirements: []
|
342
|
-
|
394
|
+
rubyforge_project:
|
395
|
+
rubygems_version: 2.7.8
|
343
396
|
signing_key:
|
344
397
|
specification_version: 4
|
345
398
|
summary: Flux Stores and more for Hyperloop
|