|
1 | | -### Current Status: Working towards 0.1 release. See Roadmap for details. |
| 1 | +### Current Status |
2 | 2 |
|
3 | 3 |
|
4 | | -[](https://travis-ci.org/hyperstack-org/hyperstack) |
| 4 | +[](https://travis-ci.com/hyperstack-org/hyperstack) |
| 5 | +[](https://badge.fury.io/rb/rails-hyperstack) |
| 6 | +[]([](https://join.slack.com/t/hyperstack-org/shared_invite/enQtNTg4NTI5NzQyNTYyLWQ4YTZlMGU0OGIxMDQzZGIxMjNlOGY5MjRhOTdlMWUzZWYyMTMzYWJkNTZmZDRhMDEzODA0NWRkMDM4MjdmNDE)) |
5 | 7 |
|
6 | | -`hyperstack-config`, `hyper-store`, and `hyper-component` are now following the public interface conventions. |
| 8 | +We now are issuing 1.0 release candidates weekly until all issues are either closed or moved to post 1.0 release status. **Your opinion matters, plus take some time to up/down vote or comment on issues of interest.** |
7 | 9 |
|
8 | | -I.e. to create a component you now do this: |
9 | 10 |
|
10 | | -```ruby |
11 | | -class MyComponent |
12 | | - include Hyperstack::Component |
13 | | - ... |
14 | | -end |
15 | | -``` |
| 11 | +| Release<br/>Date | Version | Open<br/>Issues | Documentation<br/>Sections<br/>Draft Ready | Documentation<br/>Sections<br/>WIP | |
| 12 | +|--------------|---------|-------------|-------|------| |
| 13 | +| March 29, 2021 | 1.0.alpha1.6 | 167 | 35 | 10 | |
16 | 14 |
|
17 | | -The philosophy is that you will probably have a base class defined like this: |
| 15 | +> Open issues includes enhancements, documentation, and discussion issues as well as few bugs. |
| 16 | +> |
| 17 | +> The documentation WIP (work in progress) numbers are approx, as more sections may be added. |
18 | 18 |
|
19 | | -```ruby |
20 | | -class HyperComponent |
21 | | - include Hyperstack::Component |
22 | | -end |
23 | | -``` |
| 19 | +### Contributing |
24 | 20 |
|
25 | | -Which you can then inherit from. |
26 | | - |
27 | | -The bigger change is that the state mechanism has now been greatly simplified, but you can choose when to move |
28 | | -into the future by your choice of which module to include: |
29 | | - |
30 | | -```ruby |
31 | | -class HyperComponent |
32 | | - include Hyperstack::Component |
33 | | - # to use the current state/store syntax in your components: |
34 | | - include Hyperstack::Legacy::Store |
35 | | -end |
36 | | - |
37 | | -class HyperStore |
38 | | - # to use the legacy state store syntax in your stores: |
39 | | - include Hyperstack::Legacy::Store |
40 | | -end |
41 | | -``` |
42 | | - |
43 | | -To use the new hotness change the includes: |
44 | | - |
45 | | -```ruby |
46 | | -class HyperComponent |
47 | | - include Hyperstack::Component |
48 | | - # to use the current state/store syntax in your components: |
49 | | - include Hyperstack::State::Observable |
50 | | -end |
51 | | - |
52 | | -class HyperStore |
53 | | - # to use the legacy state store syntax in your stores: |
54 | | - include Hyperstack::State::Observable |
55 | | -end |
56 | | -``` |
57 | | - |
58 | | -In summary you will need to update your hyperloop/hyperstack components and store folders to have `hyper_component.rb` |
59 | | -and `hyper_store.rb` files. And then update your components and stores to reference your application defined `HyperComponent` |
60 | | -and `HyperStore` classes. |
61 | | - |
62 | | -### The new world of state: |
63 | | - |
64 | | -Its great, its exciting, and its sooo much easier: |
65 | | - |
66 | | -Each ruby object has *state*, defined by its instance variables. Hyperstack does not define *any new state concepts*. From |
67 | | -now on you just use instance variables in your components and other objects as you normally would. |
68 | | - |
69 | | -The one caveat is that you have to *tell* the system when you are *mutating* state, and when some external entity is |
70 | | -*observing* your state. |
71 | | - |
72 | | -The `Hyperstack::State::Observable` module provides a handful of methods to make this very easy. |
73 | | - |
74 | | -Here is an example (compare to the state example on the [Hyperstack.org home page](https://hyperstack.org/)) |
75 | | - |
76 | | -```ruby |
77 | | -class UsingState < HyperComponent |
78 | | - |
79 | | - # Our component has two instance variables to keep track of what is going on |
80 | | - # @show - if true we will show an input box, otherwise the box is hidden |
81 | | - # @input_value - tracks what the user is typing into the input box. |
82 | | - # We use the mutate method to signal all observers when the state changes. |
83 | | - |
84 | | - render(DIV) do |
85 | | - # the button method returns an HTML element |
86 | | - # .on(:click) is an event handeler |
87 | | - button.on(:click) { mutate @show = !@show } |
88 | | - DIV do |
89 | | - input |
90 | | - output |
91 | | - easter_egg |
92 | | - end if @show |
93 | | - end |
94 | | - |
95 | | - def button |
96 | | - BUTTON(class: 'ui primary button') do |
97 | | - @show ? 'Hide' : 'Show' |
98 | | - end |
99 | | - end |
100 | | - |
101 | | - def input |
102 | | - DIV(class: 'ui input fluid block') do |
103 | | - INPUT(type: :text).on(:change) do |evt| |
104 | | - # we are updating the value per keypress |
105 | | - mutate @input_value = evt.target.value |
106 | | - end |
107 | | - end |
108 | | - end |
109 | | - |
110 | | - def output |
111 | | - # this will re-render whenever input_value changes |
112 | | - P { "#{@input_value}" } |
113 | | - end |
114 | | - |
115 | | - def easter_egg |
116 | | - H2 {'you found it!'} if @input_value == 'egg' |
117 | | - end |
118 | | -end |
119 | | -``` |
120 | | - |
121 | | -So to make our instance variables work with components we just need to call `mutate` when the state changes. |
122 | | - |
123 | | -Here is a very simple store that is just a global click counter |
124 | | - |
125 | | -```ruby |
126 | | -class Click |
127 | | - include Hyperstack::State::Observable |
128 | | - class << self |
129 | | - def count |
130 | | - observe @count ||= 0 |
131 | | - end |
132 | | - def inc |
133 | | - mutate @count = count + 1 |
134 | | - end |
135 | | - def count=(x) |
136 | | - mutate @count = x |
137 | | - end |
138 | | - def reset |
139 | | - mutate @count = 0 |
140 | | - end |
141 | | - end |
142 | | -end |
143 | | -``` |
144 | | - |
145 | | -Now any component can access and change the counter by calling `Click.count`, `Click.inc` and `Click.reset` as needed. |
146 | | - |
147 | | -The `observe` and `mutate` methods take no params (handy for adding to the end of a method), a single param as shown above, |
148 | | -or a block in which case the entire block will be executed before signaling the rest of the system. |
149 | | - |
150 | | -That is all there is to it, but to make things easier `Observable` contains some other helper methods which we can use: |
151 | | - |
152 | | -```ruby |
153 | | -class Click |
154 | | - include Hyperstack::State::Observable |
155 | | - class << self |
156 | | - observer(:count) { @count ||= 0 } |
157 | | - state_writer :count |
158 | | - mutator(:inc) { count = count + 1 } |
159 | | - mutator(:reset) { count = 0 } |
160 | | - end |
161 | | -end |
162 | | -``` |
163 | | - |
164 | | -The `observer` and `mutator` methods create a method wrapped in `observe` or `mutate` block. |
165 | | - |
166 | | -In addition there are `state_accessor`, `state_reader` and `state_writer` methods that work just like `attr_accessor` methods |
167 | | -except access is wrapped in the appropriate `mutate` or `observe` method. |
168 | | - |
169 | | -The methods can be used either at the class or instance level as needed. |
170 | | - |
171 | | -Because stateful components use the same `Observable` module all the above methods are available to help structure your |
172 | | -components nicely. |
173 | | - |
174 | | -Notice in the component example we never use `observe` that is because by definition components always `observe` their own |
175 | | -state automatically so you don't need to. |
| 21 | +Any and all contributions are welcome. Pull requests on documentation issues large are small are easy to do, and of great help. |
176 | 22 |
|
| 23 | +There are also a number of issues marked as `Good First Issue`. |
0 commit comments