@danielkalen/simplybind
Version:
Magically simple, framework-less one-way/two-way data binding for frontend/backend in ~5kb.
84 lines (67 loc) • 1.78 kB
JavaScript
var plastiq = require('.');
var h = plastiq.html;
module.exports = function () {
var refresh;
var throttle;
var promise, awaitingPromise, lastTime, lastValue, timeout;
var currentValue;
var currentFn;
function callFn() {
var self = this;
if (promise) {
if (!awaitingPromise) {
promise.then(function () {
promise = undefined;
awaitingPromise = undefined;
sync();
});
awaitingPromise = true;
}
} else {
var result = currentFn(currentValue);
if (result && typeof result.then === 'function') {
promise = result;
promise.then(refresh);
}
valueChanged();
lastTime = Date.now();
}
}
function valueHasChanged() {
return lastValue !== normalisedValue(currentValue);
}
function valueChanged() {
lastValue = normalisedValue(currentValue);
}
function sync() {
var self = this;
var now = Date.now();
if (valueHasChanged()) {
if (!lastTime || (lastTime + throttle < now)) {
callFn();
} else if (!timeout) {
var timeoutDuration = lastTime - now + throttle;
timeout = setTimeout(function () {
timeout = undefined;
callFn();
}, timeoutDuration);
}
}
}
return function (value, options, fn) {
if (typeof options === 'function') {
fn = options;
options = undefined;
}
refresh = h.refresh;
throttle = options && options.hasOwnProperty('throttle') && options.throttle !== undefined? options.throttle: 0;
currentValue = value;
currentFn = fn;
sync();
}
};
function normalisedValue(value) {
return value.constructor === Object || value instanceof Array
? JSON.stringify(value)
: value;
}