Comparing version 0.5.17 to 0.5.18
@@ -36,2 +36,6 @@ 'use strict'; | ||
var _PromiseQueue = require('./PromiseQueue'); | ||
var _PromiseQueue2 = _interopRequireDefault(_PromiseQueue); | ||
var _debounce = require('./debounce'); | ||
@@ -67,2 +71,3 @@ | ||
_this.maybeUpdate = (0, _bind3.default)(_this.maybeUpdate, _this); | ||
_this._updateQueue = new _PromiseQueue2.default(1); | ||
_this._propagateUpdate = (0, _debounce2.default)((0, _bind3.default)(_this._propagateUpdate, _this), 0, 0); | ||
@@ -182,6 +187,7 @@ _this._doUpdate = (0, _debounce2.default)((0, _bind3.default)(_this._doUpdate, _this), _defaultDebounce, _defaultBatchSize); | ||
/** | ||
* Execute update. Cancel previous execution if it's | ||
* exists and start new one. Set `this._updatePromise` | ||
* execution promise that resolved when update completelly | ||
* executed. | ||
* Executes an update. It is guarantee that | ||
* one `_doUpdate` will be executed at one time. | ||
* | ||
* TODO it's a bit hacky implementation, but it works well. | ||
* I can't imagine more clearly impl for now. | ||
* @return {Promise} | ||
@@ -193,7 +199,23 @@ */ | ||
value: function update() { | ||
var _this3 = this; | ||
var firstRun = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; | ||
var immidiatelly = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; | ||
this._doUpdate.cancel(); | ||
this._updatePromise = immidiatelly ? this._doUpdate.func(firstRun) : this._doUpdate(firstRun); | ||
this._updatePromise = this._updateQueue.add(function () { | ||
_this3._updatePromise = immidiatelly ? _this3._doUpdate.func(firstRun) : _this3._doUpdate(firstRun); | ||
if (immidiatelly) { | ||
return _this3._updatePromise; | ||
} else { | ||
if (_this3._updatePromise.debouncePassed) { | ||
return _this3._updatePromise; | ||
} else { | ||
return Promise.resolve('__debounced__'); | ||
} | ||
} | ||
}).then(function (res) { | ||
return res === '__debounced__' ? _this3._updatePromise : res; | ||
}); | ||
return this._updatePromise; | ||
@@ -284,3 +306,3 @@ } | ||
value: function _doUpdate() { | ||
var _this3 = this; | ||
var _this4 = this; | ||
@@ -290,4 +312,4 @@ var firstRun = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; | ||
return this.exec().then(function (result) { | ||
_this3._updateLatestIds(); | ||
return _this3._propagateUpdate(firstRun).then(function () { | ||
_this4._updateLatestIds(); | ||
return _this4._propagateUpdate(firstRun).then(function () { | ||
return result; | ||
@@ -294,0 +316,0 @@ }); |
@@ -51,2 +51,3 @@ "use strict"; | ||
var returnPromise = promise; | ||
returnPromise.debouncePassed = true; | ||
clearTimeout(timeout); | ||
@@ -66,7 +67,5 @@ _maybeResolve(); | ||
}; | ||
var updateWait = function updateWait(newWait) { | ||
wait = newWait; | ||
}; | ||
var cancel = function cancel() { | ||
@@ -73,0 +72,0 @@ clearTimeout(timeout); |
@@ -7,2 +7,3 @@ import _bind from 'fast.js/function/bind'; | ||
import EJSON from './EJSON'; | ||
import PromiseQueue from './PromiseQueue'; | ||
import debounce from './debounce'; | ||
@@ -23,2 +24,3 @@ | ||
this.maybeUpdate = _bind(this.maybeUpdate, this); | ||
this._updateQueue = new PromiseQueue(1); | ||
this._propagateUpdate = debounce(_bind(this._propagateUpdate, this), 0, 0); | ||
@@ -141,13 +143,31 @@ this._doUpdate = debounce( | ||
/** | ||
* Execute update. Cancel previous execution if it's | ||
* exists and start new one. Set `this._updatePromise` | ||
* execution promise that resolved when update completelly | ||
* executed. | ||
* Executes an update. It is guarantee that | ||
* one `_doUpdate` will be executed at one time. | ||
* | ||
* TODO it's a bit hacky implementation, but it works well. | ||
* I can't imagine more clearly impl for now. | ||
* @return {Promise} | ||
*/ | ||
update(firstRun = false, immidiatelly = false) { | ||
this._doUpdate.cancel(); | ||
this._updatePromise = immidiatelly | ||
? this._doUpdate.func(firstRun) | ||
: this._doUpdate(firstRun); | ||
this._updatePromise = this._updateQueue.add(() => { | ||
this._updatePromise = immidiatelly | ||
? this._doUpdate.func(firstRun) | ||
: this._doUpdate(firstRun); | ||
if (immidiatelly) { | ||
return this._updatePromise; | ||
} else { | ||
if (this._updatePromise.debouncePassed) { | ||
return this._updatePromise; | ||
} else { | ||
return Promise.resolve('__debounced__'); | ||
} | ||
} | ||
}) | ||
.then(res => | ||
res === '__debounced__' | ||
? this._updatePromise | ||
: res | ||
); | ||
return this._updatePromise; | ||
@@ -154,0 +174,0 @@ } |
@@ -45,2 +45,3 @@ /** | ||
const returnPromise = promise; | ||
returnPromise.debouncePassed = true; | ||
clearTimeout(timeout); | ||
@@ -57,10 +58,9 @@ maybeResolve(); | ||
const updateBatchSize = function(newBatchSize) { | ||
batchSize = newBatchSize; | ||
}; | ||
const updateWait = function(newWait) { | ||
wait = newWait; | ||
}; | ||
const cancel = function() { | ||
@@ -67,0 +67,0 @@ clearTimeout(timeout); |
{ | ||
"name": "marsdb", | ||
"version": "0.5.17", | ||
"version": "0.5.18", | ||
"author": { | ||
@@ -5,0 +5,0 @@ "name": "Artem Artemev", |
@@ -73,3 +73,3 @@ import Collection from '../../lib/Collection'; | ||
cursor.on('update', cb1); | ||
cursor.debounce(10); | ||
cursor.debounce(50); | ||
cursor.update(); | ||
@@ -410,25 +410,48 @@ cursor.update(); | ||
describe('#update', function () { | ||
it('should stop previous update and return new one', function () { | ||
const cursor = new CursorObservable(db); | ||
cursor._doUpdate = sinon.spy(); | ||
cursor._doUpdate.func = sinon.spy(); | ||
cursor._doUpdate.cancel = sinon.spy(); | ||
it('should guarantee that only one _doUpdate invoked at one time', function () { | ||
const beforeUpdateCall = sinon.spy(); | ||
const doUpdateCall = sinon.spy(); | ||
class OtherCursor extends CursorObservable { | ||
_doUpdate(...args) { | ||
beforeUpdateCall(); | ||
return new Promise((resolve) => { | ||
setTimeout(resolve, 50); | ||
}).then(() => { | ||
return super._doUpdate(...args); | ||
}).then((res) => { | ||
doUpdateCall(); | ||
return res; | ||
}); | ||
} | ||
} | ||
cursor.update(); | ||
cursor._doUpdate.cancel.should.have.callCount(1); | ||
cursor._doUpdate.should.have.callCount(1); | ||
const cursor = new OtherCursor(db); | ||
cursor.batchSize(2); | ||
cursor.debounce(50); | ||
const initUpd = cursor.update(true, true); | ||
const upd2 = cursor.update(); | ||
const upd3 = cursor.update(); | ||
//beforeUpdateCall.should.have.callCount(0); | ||
return Promise.resolve().then(() => { | ||
beforeUpdateCall.should.have.callCount(1); | ||
cursor.update(); | ||
cursor.update(); | ||
cursor.update(); | ||
const upd4 = cursor.update(); | ||
beforeUpdateCall.should.have.callCount(1); | ||
return initUpd.then(() => { | ||
beforeUpdateCall.should.have.callCount(1); | ||
return upd3; | ||
}) | ||
.then(() => { | ||
beforeUpdateCall.should.have.callCount(2); | ||
doUpdateCall.should.have.callCount(2); | ||
return upd4; | ||
}) | ||
.then(() => { | ||
beforeUpdateCall.should.have.callCount(4); | ||
doUpdateCall.should.have.callCount(4); | ||
}); | ||
}) | ||
}); | ||
it('should immidiatelly call _doUpdate and return result Promise', function () { | ||
const cursor = new CursorObservable(db); | ||
cursor._doUpdate = sinon.spy(); | ||
cursor._doUpdate.func = sinon.stub(); | ||
cursor._doUpdate.func.returns(1); | ||
cursor._doUpdate.cancel = sinon.spy(); | ||
const res = cursor.update(false, true); | ||
cursor._doUpdate.func.should.have.callCount(1); | ||
cursor._doUpdate.should.have.callCount(0); | ||
cursor._doUpdate.cancel.should.have.callCount(1); | ||
res.should.be.equal(1); | ||
}); | ||
}); | ||
@@ -435,0 +458,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
972648
22397
80