rbdux 0.1 → 0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e2b52fe3fdf03fb4b57e8875edf152dfa7dba39
4
- data.tar.gz: 2a4cdd6c7dd86694bac2dee6af8fddeb793bdbed
3
+ metadata.gz: 696d9041db4b07c10faa88172f0caf377671d414
4
+ data.tar.gz: 0119532c811ec2326d07bc5e4a81a067901bb7dd
5
5
  SHA512:
6
- metadata.gz: 7bbe51b93c102910fac95498117eff8774c924448bcb3b7e7308b8cf5f204f605321eb4bccc6c0cf2d1835d0674872cd1e6c1b20f64e6e16a7f38919d53f9b7a
7
- data.tar.gz: 0b81e094159550b1bad1fe2508471abf88c9fb7a350c8ba2230f6c52320cca4e351f8b1bc61a836f918a2f5338dab073ba3fe612e00abacc80fb3f2d52559b0d
6
+ metadata.gz: cd12a4029311954a642eb2319afd055afee8ccadfe2ed9f9c7a679e1a7936f0329eb00cf106fd7be02a58ab4c5f4172c4aadbb93e09af393ff8c612b98c44f9b
7
+ data.tar.gz: 13ff0be159045cff7f3370ae228f310ca342b47f07358c2610e859f2d4af573de3817a4e2aeae6ae725642b228f2b38e0fb88315b3f0ed5bf0d89c1bd73b5f50
@@ -0,0 +1,5 @@
1
+ module Rbdux
2
+ module Errors
3
+ MissingStoreContainerError = Class.new(StandardError)
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module Rbdux
2
+ module Middleware
3
+ class Thunk
4
+ def before(store, action)
5
+ func = action.class.dispatch_func
6
+
7
+ return nil unless func
8
+
9
+ func.call(store, action)
10
+ end
11
+ end
12
+ end
13
+ end
data/lib/rbdux/store.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'securerandom'
2
+ require_relative 'errors'
2
3
 
3
4
  module Rbdux
4
5
  class Store
@@ -13,10 +14,6 @@ module Rbdux
13
14
  @instance = nil
14
15
  end
15
16
 
16
- def with_state(state)
17
- @instance = Store.new(state)
18
- end
19
-
20
17
  def method_missing(method, *args, &block)
21
18
  return unless instance.respond_to?(method)
22
19
 
@@ -24,50 +21,54 @@ module Rbdux
24
21
  end
25
22
  end
26
23
 
27
- attr_reader :state
24
+ def with_store(store)
25
+ raise ArgumentError, 'You must provide a store.' unless store
28
26
 
29
- def reduce(action, state_key = nil, &block)
30
- add_reducer(action, state_key, true, block)
27
+ @store_container = store
31
28
 
32
29
  self
33
30
  end
34
31
 
35
- def reduce_and_merge(action, state_key = nil, &block)
36
- add_reducer(action, state_key, false, block)
32
+ def add_middleware(middleware)
33
+ @before_middleware << middleware if middleware.respond_to? :before
34
+ @after_middleware << middleware if middleware.respond_to? :after
37
35
 
38
36
  self
39
37
  end
40
38
 
41
- def when_merging(&block)
42
- validate_functional_inputs(block)
43
-
44
- @merge_func = block
39
+ def get(state_key = nil)
40
+ validate_store_container
45
41
 
46
- self
42
+ if state_key
43
+ @store_container.get(state_key)
44
+ else
45
+ @store_container.get_all
46
+ end
47
47
  end
48
48
 
49
- def before(&block)
50
- @before_middleware << block if block
49
+ def reduce(action, state_key = nil, &block)
50
+ validate_functional_inputs(block)
51
51
 
52
- self
53
- end
52
+ key = action.name
54
53
 
55
- def after(&block)
56
- @after_middleware << block if block
54
+ reducers[key] = [] unless reducers.key?(key)
55
+ reducers[key] << Reducer.new(state_key, block)
57
56
 
58
57
  self
59
58
  end
60
59
 
61
60
  def dispatch(action)
62
- previous_state = state
61
+ validate_store_container
62
+
63
+ previous_state = @store_container.get_all
63
64
 
64
- dispatched_action = apply_before_middleware(action)
65
+ dispatched_action = apply_before_middleware!(action)
65
66
 
66
67
  reducers.fetch(action.class.name, []).each do |reducer|
67
68
  apply_reducer!(reducer, dispatched_action)
68
69
  end
69
70
 
70
- apply_after_middleware(previous_state, dispatched_action)
71
+ apply_after_middleware!(previous_state, dispatched_action)
71
72
 
72
73
  observers.values.each(&:call)
73
74
  end
@@ -88,79 +89,52 @@ module Rbdux
88
89
 
89
90
  private
90
91
 
91
- Reducer = Struct.new(:state_key, :auto_merge, :func)
92
+ Reducer = Struct.new(:state_key, :func)
92
93
 
93
94
  attr_reader :observers, :reducers
94
95
 
95
- def initialize(state = {})
96
- @state = state
96
+ def initialize
97
97
  @observers = {}
98
98
  @reducers = {}
99
99
  @before_middleware = []
100
100
  @after_middleware = []
101
- @merge_func = nil
102
101
  end
103
102
 
104
- def add_reducer(action, state_key, auto_merge, func)
105
- validate_functional_inputs(func)
106
-
107
- key = action.name
108
-
109
- reducers[key] = [] unless reducers.key?(key)
110
- reducers[key] << Reducer.new(state_key, auto_merge, func)
111
- end
112
-
113
- def apply_before_middleware(action)
103
+ def apply_before_middleware!(action)
114
104
  dispatched_action = action
115
105
 
116
106
  @before_middleware.each do |m|
117
- new_action = m.call(self, dispatched_action)
107
+ new_action = m.before(self, dispatched_action)
118
108
  dispatched_action = new_action unless new_action.nil?
119
109
  end
120
110
 
121
111
  dispatched_action
122
112
  end
123
113
 
124
- def apply_after_middleware(previous_state, action)
114
+ def apply_after_middleware!(previous_state, action)
125
115
  @after_middleware.each do |m|
126
- m.call(previous_state, state, action)
116
+ m.after(previous_state, get, action)
127
117
  end
128
118
  end
129
119
 
130
120
  def apply_reducer!(reducer, action)
131
- reducer_params = [slice_state(reducer.state_key), action]
132
- reducer_params << state unless reducer.auto_merge
133
- new_state = reducer.func.call(*reducer_params)
121
+ new_state = reducer.func.call(get(reducer.state_key), action)
134
122
 
135
123
  return if new_state.nil?
136
124
 
137
- @state = if reducer.auto_merge
138
- merge_state(new_state, reducer.state_key)
139
- else
140
- new_state
141
- end
142
- end
143
-
144
- def slice_state(state_key)
145
- return state unless state_key
146
-
147
- state[state_key]
148
- end
149
-
150
- def merge_state(new_state, state_key)
151
- if @merge_func.nil?
152
- default_merge(state, new_state, state_key)
125
+ if reducer.state_key
126
+ @store_container.set(reducer.state_key, new_state)
153
127
  else
154
- @merge_func.call(state, new_state, state_key)
128
+ @store_container.replace(new_state)
155
129
  end
156
130
  end
157
131
 
158
- def default_merge(old_state, new_state, state_key)
159
- old_state.dup.merge(state_key ? { state_key => new_state } : new_state)
160
- end
161
-
162
132
  def validate_functional_inputs(block)
163
133
  raise ArgumentError, 'You must define a block.' unless block
164
134
  end
135
+
136
+ def validate_store_container
137
+ raise Rbdux::Errors::MissingStoreContainerError unless @store_container
138
+ end
165
139
  end
166
140
  end
@@ -0,0 +1,35 @@
1
+ require 'hamster'
2
+
3
+ module Rbdux
4
+ module Stores
5
+ class ImmutableMemoryStore
6
+ def self.with_state(state)
7
+ ImmutableMemoryStore.new(state)
8
+ end
9
+
10
+ def get(key)
11
+ state[key]
12
+ end
13
+
14
+ def get_all
15
+ state.to_h
16
+ end
17
+
18
+ def set(key, value)
19
+ @state = state.put(key, value)
20
+ end
21
+
22
+ def replace(state)
23
+ @state = Hamster::Hash.new(state)
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :state
29
+
30
+ def initialize(state)
31
+ @state = Hamster::Hash.new(state)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ module Rbdux
2
+ module Stores
3
+ class MemoryStore
4
+ def self.with_state(state)
5
+ MemoryStore.new(state)
6
+ end
7
+
8
+ def get(key)
9
+ state[key]
10
+ end
11
+
12
+ def get_all
13
+ state
14
+ end
15
+
16
+ def set(key, value)
17
+ state[key] = value
18
+ end
19
+
20
+ def replace(state)
21
+ @state = state
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :state
27
+
28
+ def initialize(state)
29
+ @state = state
30
+ end
31
+ end
32
+ end
33
+ end
data/lib/rbdux.rb CHANGED
@@ -1,3 +1,5 @@
1
1
  require 'rbdux/action'
2
2
  require 'rbdux/store'
3
- require 'rbdux/middleware/dispatch_interceptor'
3
+ require 'rbdux/errors'
4
+ require 'rbdux/stores/memory_store'
5
+ require 'rbdux/middleware/thunk'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbdux
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Tompkins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-02 00:00:00.000000000 Z
11
+ date: 2016-08-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: josh@joshtompkins.com
@@ -18,8 +18,11 @@ extra_rdoc_files: []
18
18
  files:
19
19
  - lib/rbdux.rb
20
20
  - lib/rbdux/action.rb
21
- - lib/rbdux/middleware/dispatch_interceptor.rb
21
+ - lib/rbdux/errors.rb
22
+ - lib/rbdux/middleware/thunk.rb
22
23
  - lib/rbdux/store.rb
24
+ - lib/rbdux/stores/immutable_memory_store.rb
25
+ - lib/rbdux/stores/memory_store.rb
23
26
  homepage: https://github.com/jtompkins/rbdux
24
27
  licenses:
25
28
  - MIT
@@ -1,13 +0,0 @@
1
- module Rbdux
2
- module Middleware
3
- module_function
4
-
5
- def dispatch_interceptor(store, action)
6
- func = action.class.dispatch_func
7
-
8
- return nil unless func
9
-
10
- func.call(store, action)
11
- end
12
- end
13
- end