Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/oakfang/xain
Using ES2015 proxies to simplify observation and reaction
https://github.com/oakfang/xain
Last synced: 6 days ago
JSON representation
Using ES2015 proxies to simplify observation and reaction
- Host: GitHub
- URL: https://github.com/oakfang/xain
- Owner: oakfang
- License: mit
- Created: 2016-05-01T11:51:12.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2016-06-30T08:27:47.000Z (over 8 years ago)
- Last Synced: 2024-12-10T14:18:32.981Z (about 1 month ago)
- Language: JavaScript
- Size: 8.79 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# xain
Using ES2015 proxies to simplify observation and reaction## Usage
### Simple observation
```js
'use strict';const {observable, observe} = require('xian');
const o = observable({
foo: 1
});
let count = 0;
const unobserve = observe(o, (prop, newValue, oldValue) => count += 1); // returns a funtion that, when called, stops the observation
// count == 0
o.foo = 1;
// count == 0
o.foo = 2;
o.foo = 2;
// count == 1
o.foo = 1;
// count == 2
unobserve(); // stop the observer
o.foo = 5;
o.foo = 6;
o.foo = 7;
// count == 2
```### Batched observation
(Use when you make several changes and you want to get the diff, if it exists, between the first and last changes on this tick)
```js
const o = observable({
foo: 1
}, true); // notice the `true` parameter indicating it is batched
let count = 0;
observe(o, () => count += 1);
// count == 0
o.foo = 0;
// count == 0
o.foo = 2;
o.foo = 2;
// count == 0
process.nextTick(() => {
// count == 1, and oldValue will be 1 and newValue will be 2, skipping the 0 in between
});
```### Reactive links
```js
const x = require('xian');const o = x.observable({
x: 3,
y: 6
});
let counter = 0;
const r = x.reactive({ // note: every reactive object is also `observable`, and thus can be passed to the `observe` function.
x: x.pipe(o, 'x'), // pipe changes through
y: x.pipe(o, 'y'),
z: x.link(o, ({x, y}) => { // link changes of dependencies into a new value
counter += 1;
return x + y;
})
});
t.is(r.x, 3);
t.is(r.y, 6);
t.is(r.z, 9);
t.is(counter, 1);
o.x = 3;
t.is(r.x, 3);
t.is(r.y, 6);
t.is(r.z, 9);
t.is(counter, 1);
o.x = 5;
t.is(r.x, 5);
t.is(r.y, 6);
t.is(r.z, 11);
t.is(counter, 2);
```**Note:** a `link` function must always `get` every single dependency every time it runs.
The easiest way is to destructure the observable (the actual argument passed to the link function)
into the properties the link depends upon.### Observable streams
```js
const x = require('xain');const o = x.observable({
x: 3,
y: 6
});
const str = x.stream(o)
.filter(key => key === 'x')
.map((key, nval, oval) => oval)
.reduce((acc, val) => acc + val, 0);
const expected = [3, 4, 2];
let actual = [];
x.observe(str, v => actual.push(v));
o.x = 1;
o.x = -2;
o.x = 5;
t.is(expected[0], actual[0]);
t.is(expected[1], actual[1]);
t.is(expected[2], actual[2]);
```