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.
@@ -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
@@ -0,0 +1,7 @@
1
+ module Hyperstack
2
+ module Legacy
3
+ module Store
4
+ VERSION = '1.0.alpha1'
5
+ end
6
+ end
7
+ 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.99.6
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: 2019-01-30 00:00:00.000000000 Z
13
+ date: 2018-11-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: hyperloop-config
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.99.6
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.99.6
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.99.6
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.99.6
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.99.6
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.99.6
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.2.4
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.2.4
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/hyper-store/class_methods.rb
312
- - lib/hyper-store/dispatch_receiver.rb
313
- - lib/hyper-store/instance_methods.rb
314
- - lib/hyper-store/mutator_wrapper.rb
315
- - lib/hyper-store/state_wrapper.rb
316
- - lib/hyper-store/state_wrapper/argument_validator.rb
317
- - lib/hyper-store/version.rb
318
- - lib/hyperloop/application/boot.rb
319
- - lib/hyperloop/store.rb
320
- - lib/hyperloop/store/mixin.rb
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: '0'
392
+ version: 1.3.1
341
393
  requirements: []
342
- rubygems_version: 3.0.2
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