Observable computed state
Более подробно на русском языке
// event-config.js
module.exports = {
start: { type: 'Number' },
end: { type: 'Number' },
duration: {
type: 'Number',
computed: ['start', 'end', function(start, end) {
if (start === null || end === null) { return null; }
return end - start;
}]
}
};
// main.js
var state = new ComputedState(eventConfig);
state.subscribe(function(changedKeys, event) {
expect(changedKeys).to.deep.equal([
'start', 'end', 'duration'
]);
expect(event.start).to.equal(15);
expect(event.end).to.equal(24);
expect(event.duration).to.equal(9);
done();
});
state.update({ start: 15, end: 24 });
More examples in the 'test' folder.
- no 'undefined' values, only 'null's
- simple separated configuration
- works like Excel / Google sheets
DB:UPDATE
state.update({
bar: 'foo', // simple property
'student.name': 'John', // a property of internal object
'countries.usa.area': 123 // array with item: id = 'usa'
})
DB:INSERT
state.insertItem('countries', { id: 'usa', name: 'USA' }
DB:DELETE
state.removeItem('countries', 'usa');
DB:TRIGGER
var callback = function(changedKeys, stateNew) { };
state.subscribe(callback, ['watchedKeys']);
Usage:
- Load external data, like XHR ajax requests
- Timeouts
- Promises
- DOM manipulation
- etc.
module.exports = {
// simple writable property
endpoint: { type: 'Text' },
// async computed property
weather: {
type: 'Number',
computedAsync: ['endpoint', function(endpoint, resolve, reject) {
if (endpoint === null) { return null; }
// update externally
var timeoutInstance = setTimeout(function() {
var demoWeather = 32;
resolve(demoWeather);
// reject('error message or code');
}, 500);
// return a function that cancels this timeout
return clearTimeout.bind(null, timeoutInstance);
}]
},
// a computed property, based on 'weather' async property
weatherMessage: {
type: 'Text',
computed: ['weather', function(weatherAsync) {
if (weatherAsync === null || weatherAsync.data === null) {
return null;
}
return 'The weather is ' + weatherAsync.data;
}]
}
How async works:
- a user updates 'endpoint' = 'someUrl'
Sync computation:
- recalculates 'weather': set to null
- recalculates 'weatherMessage': set to null
Async computation:
- runs async 'weather' calculation (automatically)
- recalculates 'weather': set to { data: 32, error: null }
- recalculates 'weatherMessage': set to 'The weather is 32'