Commit 70d5c3b0a81181ecad4e03f0b36c0e3cf11a5de4
Merge pull request #12 from dominictarr/patch-3
basic documentationMatt McKegg authored on 6/20/2017, 12:23:32 AM
GitHub committed on 6/20/2017, 12:23:32 AM
Parent: 306cee2cea33ec6d7ac5025d5033784134e56141
Parent: 081e63777891a3beac5175e8a1a7ef82783490eb
Files changed
README.md | changed |
README.md | |||
---|---|---|---|
@@ -95,32 +95,82 @@ | |||
95 | 95 … | ## Types | |
96 | 96 … | ||
97 | 97 … | Observables that store data | |
98 | 98 … | ||
99 | -- Array | ||
100 | -- Dict | ||
101 | -- Set | ||
102 | -- Struct | ||
103 | -- Value | ||
99 … | +- [Array](#Array) | ||
100 … | +- [Dict](#Dict) | ||
101 … | +- [Set](#Set) | ||
102 … | +- [Struct](#Struct) | ||
103 … | +- [Value](#Struct) | ||
104 | 104 … | - MappedArray | |
105 | 105 … | - MappedDict | |
106 | 106 … | ||
107 … | +### Value | ||
108 … | + | ||
109 … | +The classic observable - stores a single value, updates listeners when the values changes. | ||
110 … | + | ||
111 … | +``` js | ||
112 … | +var Value = require('mutant/value') | ||
113 … | + | ||
114 … | +var v = Value() | ||
115 … | +v.set(true) | ||
116 … | +//set listener | ||
117 … | +v(function (_v) { ... }) | ||
118 … | +``` | ||
119 … | + | ||
120 … | +This is almost the same as [observable](https://github.com/dominictarr/observable) and [observ](https://github.com/raynos/observ). There's only a couple of small differences: you can specify a default value (fallback when null) and it will throw if you try and add a non-function as a listener (this one always got me) | ||
121 … | + | ||
122 … | + | ||
107 | 123 … | ### Array | |
108 | 124 … | ||
125 … | +An observable with additional _array like_ methods, which update the observable. The array items can be ordinary | ||
126 … | +values or observables. | ||
127 … | + | ||
109 | 128 … | Like [observ-array](https://github.com/raynos/observ-array) but as with struct, emits the same object. No constant shallow cloning on every change. You can push observables (or ordinary values) and it will emit whenever any of them change. Works well with mutant/map. | |
110 | 129 … | ||
111 | 130 … | There's also `mutant/set` which is similar but only allows values to exist once. | |
112 | 131 … | ||
132 … | +additional methods: | ||
133 … | +* `array.put(index, value)` set item at `index` to `value` | ||
134 … | +* `array.push(value)` append `value` to end of `array`. | ||
135 … | +* `array.pop()` remove item from end. | ||
136 … | +* `array.shift()` remove item from start. | ||
137 … | +* `array.clear()` remove all items. | ||
138 … | +* `array.insert(value, index)` equivalent to `[].splice(index, 0, value)` on a standard js array. | ||
139 … | +* `array.delete(value)` remove the first occurance of `value` from the array. | ||
140 … | +* `array.deleteAt(index)` remove item at `index`. | ||
141 … | +* `array.transaction(fn)` apply a series of changes to the array and then update listeners in one go. | ||
113 | 142 … | ||
114 | 143 … | ### Dict | |
115 | 144 … | ||
116 | -... | ||
145 … | +The complement to [Struct](#Struct) - but instead of representing a fixed set of sub-observables, it's a single observable which you can add sub-keys to. | ||
117 | 146 … | ||
147 … | +``` js | ||
148 … | +var Dict = require('mutant/dict') | ||
149 … | +var d = Dict() | ||
150 … | +d.put('key', 1) | ||
151 … | +d(function (v) { | ||
152 … | + // => {key: 1} | ||
153 … | +}) | ||
118 | 154 … | ||
155 … | +``` | ||
156 … | + | ||
157 … | +additional methods: | ||
158 … | +* `dict.put(key, value)` set property `key` to `value` | ||
159 … | +* `dict.delete(key)` remove property `key` | ||
160 … | +* `dict.has(key)` returns true if `key` is present. | ||
161 … | +* `dict.keys()` return array of keys. | ||
162 … | + | ||
119 | 163 … | ### Set | |
120 | 164 … | ||
121 | -... | ||
165 … | +Represents a collection like [Array](#Array) except without ordering. | ||
122 | 166 … | ||
167 … | +additional methods: | ||
168 … | +* `set.add(value)` add `value` to the set. | ||
169 … | +* `set.clear()` remove all items. | ||
170 … | +* `set.has()` check if item is in the set. | ||
171 … | +* `set.get(index)` get the item at `index` in the underlying array | ||
172 … | +* `set.getLength()` get the number of items in the set. | ||
123 | 173 … | ||
124 | 174 … | ### Struct | |
125 | 175 … | ||
126 | 176 … | Mostly the same as [observ-struct](https://github.com/raynos/observ-struct) except that it always emits the same object (with the properties changed). This means it violates immutability, but the trade-off is less garbage collection. The rest of the mutant helpers can handle this case pretty well. | |
@@ -139,13 +189,8 @@ | |||
139 | 189 … | ||
140 | 190 … | You can use these as your primary state atoms. I often use them like classes, extending them with additional methods to help with a given role. Another nice side effect is they work great for serializing/deserializing state. You can call them with `JSON.stringify(struct())` to get their entire tree state, then call them again later with `struct.set(JSON.parse(data))` to put it back. This is how state and file persistence works in [Loop Drop](https://github.com/mmckegg/loop-drop-app). | |
141 | 191 … | ||
142 | 192 … | ||
143 | -### Value | ||
144 | - | ||
145 | -This is almost the same as [observable](https://github.com/dominictarr/observable) and [observ](https://github.com/raynos/observ). There's only a couple of small differences: you can specify a default value (fallback when null) and it will throw if you try and add a non-function as a listener (this one always got me) | ||
146 | - | ||
147 | - | ||
148 | 193 … | ### MappedArray | |
149 | 194 … | ||
150 | 195 … | ... | |
151 | 196 … | ||
@@ -184,21 +229,31 @@ | |||
184 | 229 … | ## Transforms | |
185 | 230 … | ||
186 | 231 … | Take one or more observables and transform them into an observable | |
187 | 232 … | ||
188 | -- computed | ||
233 … | +- [Computed](#Computed) | ||
189 | 234 … | - concat | |
190 | 235 … | - dictToCollection | |
191 | 236 … | - idleProxy | |
192 | 237 … | - keys | |
193 | 238 … | - lookup | |
194 | -- map | ||
239 … | +- [Map](#Map) | ||
195 | 240 … | - merge | |
196 | 241 … | - throttle | |
197 | 242 … | - when | |
198 | 243 … | ||
199 | 244 … | ### computed | |
200 | 245 … | ||
246 … | +Take an array of observables, and map them through a function that to produce a custom observable. | ||
247 … | + | ||
248 … | +``` js | ||
249 … | +//observable that is true if A or B are true | ||
250 … | + | ||
251 … | +var Computed = require('mutant/computed') | ||
252 … | + | ||
253 … | +var aOrB = Computed([a, b], function (a, b) { return a || b }) | ||
254 … | +``` | ||
255 … | + | ||
201 | 256 … | Once again, similar to the observ and observable implementations. It has a few key differences though. | |
202 | 257 … | ||
203 | 258 … | - It will try to avoid computing if its inputs have not changed. | |
204 | 259 … | - It also won't emit a change if the new computed value is the same as the old one. This helps to prevent additional work duplication and render noise downstream. | |
@@ -207,8 +262,17 @@ | |||
207 | 262 … | - It accepts non-observable values too. This makes it possible to pass all state to a shared computed function (no need to waste more memory on those extra closures) | |
208 | 263 … | - If the value returned by the compute function is an observable, it will bind to this and emit the resolve values. Crazy nested computes FTW! | |
209 | 264 … | - These extra features do take up a bit of extra memory so I use an internal prototype (not visible to api) to reduce the footprint below that of observable and observ/computed | |
210 | 265 … | ||
266 … | +### map | ||
267 … | + | ||
268 … | +Apply a function to the value in another observable and update whenever that observable updates. Like computed, but for only one input. | ||
269 … | + | ||
270 … | +A `through` transform. It won't do any work and won't listen to its parents unless it has a listener. Calls your function with the original observable object (not the resolve value). You can then return an additional observable value as its result. It has methods on it that make it behave like an array. | ||
271 … | + | ||
272 … | +One of the most interesting features is its `maxTime` option. This is a ms value that specifies the max time to spend in a tight loop before emit the changes so far. This makes rendering large datasets to DOM elements much more responsive - a lot more like how the browser does it when it parses html. Things load in little chunks down the page. This for me has made it much easier to build apps that feel responsive and leave the main thread available for more important things (like playing sound). | ||
273 … | + | ||
274 … | + | ||
211 | 275 … | ### concat | |
212 | 276 … | ||
213 | 277 … | ... | |
214 | 278 … | ||
@@ -232,15 +296,9 @@ | |||
232 | 296 … | ||
233 | 297 … | ... | |
234 | 298 … | ||
235 | 299 … | ||
236 | -### map | ||
237 | 300 … | ||
238 | -A `through` transform. It won't do any work and won't listen to its parents unless it has a listener. Calls your function with the original observable object (not the resolve value). You can then return an additional observable value as its result. It has methods on it that make it behave like an array. | ||
239 | - | ||
240 | -One of the most interesting features is its `maxTime` option. This is a ms value that specifies the max time to spend in a tight loop before emit the changes so far. This makes rendering large datasets to DOM elements much more responsive - a lot more like how the browser does it when it parses html. Things load in little chunks down the page. This for me has made it much easier to build apps that feel responsive and leave the main thread available for more important things (like playing sound). | ||
241 | - | ||
242 | - | ||
243 | 301 … | ### merge | |
244 | 302 … | ||
245 | 303 … | ... | |
246 | 304 … |
Built with git-ssb-web