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 +4 -4
- data/README.md +75 -3
- data/lib/grand_central.rb +1 -0
- data/lib/grand_central/model.rb +31 -0
- data/lib/grand_central/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd1b1c7c87a6efc6be8b3d4a31696e63030ddf63
|
4
|
+
data.tar.gz: 5102d9ab68fff6598986b688fe109827ec42b621
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
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
|
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.
|
data/lib/grand_central.rb
CHANGED
@@ -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
|
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.
|
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-
|
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.
|
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:
|