grand_central 0.2.1 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: db799a36024cf51a5bb7f773c960004e73e46f14
4
- data.tar.gz: 834c42bf7db774cd5e0f5a98ae401875d82cb71f
3
+ metadata.gz: bd1b1c7c87a6efc6be8b3d4a31696e63030ddf63
4
+ data.tar.gz: 5102d9ab68fff6598986b688fe109827ec42b621
5
5
  SHA512:
6
- metadata.gz: c4f09955fcecc0f4df052ecb182867995f6f3cd0b1998c4e743f32041a8b83083717261fac6cb4ac3f0f3bdb2daf293a421a471ea2b1950c7612f5a57efea097
7
- data.tar.gz: b86b2ef1799904b35ead134b2100dbbcd2167800addcec339b442c8812f52236cf9ccf50fcba3f914e870f2f40ecfe0d360e50765161ead5c4fcfd875f43eb18
6
+ metadata.gz: 45c960f0d712c8f9d7e1ae80a44f6f323687d755ae7ccedcf3b3607cd64f45e64cbe1a828c59c9e22f54102def1f2b58ece490187093a23f14996e77e4eaebbd
7
+ data.tar.gz: 8ef41c15f98fe3eb3b9abe8ddb97db82156385491be383750c40944e896c2d2af756e617a79b8b4edbd4af4db706c48ac71616dcf7bb8bcdeb8cc61643d8025b
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  GrandCentral is a state-management and action-dispatching library for Opal apps. It was created with [Clearwater](https://github.com/clearwater-rb/clearwater) apps in mind, but there's no reason you couldn't use it with other types of Opal apps.
4
4
 
5
- GrandCentral is based on ideas similar to [Redux](http://rackt.github.io/redux/). You have a central store that holds all your state. This state is updated via a reducer block when you dispatch actions to the store.
5
+ GrandCentral is based on ideas similar to [Redux](http://rackt.github.io/redux/). You have a central store that holds all your state. This state is updated via a handler block when you dispatch actions to the store.
6
6
 
7
7
  ## Installation
8
8
 
@@ -22,7 +22,7 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- First, you'll need a store. You'll need to seed it with initial state and give it a reducer function:
25
+ First, you'll need a store. You'll need to seed it with initial state and give it a handler block:
26
26
 
27
27
  ```ruby
28
28
  require 'grand_central'
@@ -69,7 +69,7 @@ module Actions
69
69
  end
70
70
  ```
71
71
 
72
- Then your reducer can use these actions to update the state more easily:
72
+ Then your handler can use these actions to update the state more easily:
73
73
 
74
74
  ```ruby
75
75
  store = GrandCentral::Store.new(todos: []) do |state, action|
@@ -111,6 +111,78 @@ end
111
111
 
112
112
  Notice the `unless old_state.equal?(new_state)` clause. This is one of the reasons we recommend you update state by returning a new value instead of mutating it in-place. It allows you to do cache invalidation in O(1) time.
113
113
 
114
+ ## Models
115
+
116
+ We can use the `GrandCentral::Model` base class to store our objects:
117
+
118
+ ```ruby
119
+ class Person < GrandCentral::Model
120
+ attributes(
121
+ :id,
122
+ :name,
123
+ :location,
124
+ )
125
+ end
126
+ ```
127
+
128
+ This will set up a `Person` class we can instantiate with a hash of attributes:
129
+
130
+ ```ruby
131
+ jamie = Person.new(name: 'Jamie')
132
+ ```
133
+
134
+ ### Immutable Models
135
+
136
+ The attributes of a model cannot be modified once set. That is, there's no way to say `person.name = 'Foo'`. If you need to change the attributes of a model, there's a method called `update` that returns a new instance of the model with the specified attributes:
137
+
138
+ ```ruby
139
+ jamie = Person.new(name: 'Jamie')
140
+ updated_jamie = jamie.update(location: 'Baltimore')
141
+
142
+ jamie.location # => nil
143
+ updated_jamie.location # => "Baltimore"
144
+ ```
145
+
146
+ This allows you to use the `update` method in your store's handler without mutating the original reference:
147
+
148
+ ```ruby
149
+ store = GrandCentral::Store.new(person) do |person, action|
150
+ case action
151
+ when ChangeLocation
152
+ person.update(location: action.location)
153
+ else person
154
+ end
155
+ end
156
+ ```
157
+
158
+ This keeps each version of your app state intact if you need to roll back to a previous version. In fact, the app state itself can be a `GrandCentral::Model`:
159
+
160
+ ```ruby
161
+ class AppState < GrandCentral::Model
162
+ attributes(
163
+ :todos,
164
+ :people,
165
+ )
166
+ end
167
+
168
+ initial_state = AppState.new(
169
+ todos: [],
170
+ people: [],
171
+ )
172
+
173
+ store = GrandCentral::Store.new(initial_state) do |state, action|
174
+ case action
175
+ when AddPerson
176
+ state.update(people: state.people + [action.person])
177
+ when DeleteTodo
178
+ state.update(todos: state.todos - [action.todo])
179
+
180
+ else
181
+ state
182
+ end
183
+ end
184
+ ```
185
+
114
186
  ## Development
115
187
 
116
188
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,6 +1,7 @@
1
1
  require "grand_central/version"
2
2
  require "grand_central/store"
3
3
  require "grand_central/action"
4
+ require "grand_central/model"
4
5
 
5
6
  module GrandCentral
6
7
  end
@@ -0,0 +1,31 @@
1
+ require 'set'
2
+
3
+ module GrandCentral
4
+ class Model
5
+ def self.attributes *attrs
6
+ @attributes ||= Set.new
7
+ if attrs.any?
8
+ @attributes += attrs
9
+ attr_reader *attrs
10
+ end
11
+
12
+ @attributes
13
+ end
14
+
15
+ def initialize attributes={}
16
+ self.class.attributes.each do |attr|
17
+ instance_variable_set "@#{attr}", attributes[attr]
18
+ end
19
+ end
20
+
21
+ def update attributes={}
22
+ self.class.new(to_h.merge(attributes))
23
+ end
24
+
25
+ def to_h
26
+ self.class.attributes.each_with_object({}) do |attr, hash|
27
+ hash[attr] = send(attr)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,3 @@
1
1
  module GrandCentral
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grand_central
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamie Gaskins
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-12 00:00:00.000000000 Z
11
+ date: 2016-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -71,6 +71,7 @@ files:
71
71
  - grand_central.gemspec
72
72
  - lib/grand_central.rb
73
73
  - lib/grand_central/action.rb
74
+ - lib/grand_central/model.rb
74
75
  - lib/grand_central/store.rb
75
76
  - lib/grand_central/version.rb
76
77
  - lib/grand_central/versioned_store.rb
@@ -93,8 +94,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
94
  version: '0'
94
95
  requirements: []
95
96
  rubyforge_project:
96
- rubygems_version: 2.4.5.1
97
+ rubygems_version: 2.5.1
97
98
  signing_key:
98
99
  specification_version: 4
99
100
  summary: State and action management for Opal apps
100
101
  test_files: []
102
+ has_rdoc: