Comparing version 0.3.5 to 0.3.6
@@ -1,1 +0,1 @@ | ||
!function e(t,r,n){function o(i,a){if(!r[i]){if(!t[i]){var l="function"==typeof require&&require;if(!a&&l)return l(i,!0);if(u)return u(i,!0);var s=new Error("Cannot find module '"+i+"'");throw s.code="MODULE_NOT_FOUND",s}var c=r[i]={exports:{}};t[i][0].call(c.exports,function(e){var r=t[i][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[i].exports}for(var u="function"==typeof require&&require,i=0;i<n.length;i++)o(n[i]);return o}({1:[function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(r,"__esModule",{value:!0});var u=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),i=e("./AngularCursorObservable"),a=n(i),l="undefined"!=typeof window&&window.Mars?window.Mars.Collection:e("../Collection")["default"],s=function(){function e(t,r,n){o(this,e),this.$q=n,this._collection=new l(t,r)}return u(e,[{key:"ensureIndex",value:function(){var e;return this.$q.resolve((e=this._collection).ensureIndex.apply(e,arguments))}},{key:"insert",value:function(){var e;return this.$q.resolve((e=this._collection).insert.apply(e,arguments))}},{key:"insertAll",value:function(){var e;return this.$q.resolve((e=this._collection).insertAll.apply(e,arguments))}},{key:"update",value:function(){var e;return this.$q.resolve((e=this._collection).update.apply(e,arguments))}},{key:"remove",value:function(){var e;return this.$q.resolve((e=this._collection).remove.apply(e,arguments))}},{key:"find",value:function(e){return new a["default"](this,e)}},{key:"findOne",value:function(){var e;return this.$q.resolve((e=this._collection).findOne.apply(e,arguments))}},{key:"count",value:function(){var e;return this.$q.resolve((e=this._collection).count.apply(e,arguments))}},{key:"ids",value:function(){var e;return this.$q.resolve((e=this._collection).ids.apply(e,arguments))}},{key:"modelName",get:function(){return this._collection.modelName}}]),e}();r.AngularCollection=s,r["default"]=s},{"../Collection":void 0,"./AngularCursorObservable":2}],2:[function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var u=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),i=function(e,t,r){for(var n=!0;n;){var o=e,u=t,i=r;a=s=l=void 0,n=!1,null===o&&(o=Function.prototype);var a=Object.getOwnPropertyDescriptor(o,u);if(void 0!==a){if("value"in a)return a.value;var l=a.get;return void 0===l?void 0:l.call(i)}var s=Object.getPrototypeOf(o);if(null===s)return void 0;e=s,t=u,r=i,n=!0}},a="undefined"!=typeof window&&window.Mars?window.Mars.CursorObservable:e("../CursorObservable")["default"],l=function(e){function t(e,r){n(this,t),i(Object.getPrototypeOf(t.prototype),"constructor",this).call(this,e._collection,r),this.$q=e.$q}return o(t,e),u(t,[{key:"destroy",value:function(e){e&&e._prevStopper&&e._prevStopper.stop()}},{key:"observe",value:function(e,r){var n=i(Object.getPrototypeOf(t.prototype),"observe",this).call(this,e);return r&&r.$on("$destroy",function(){n.stop()}),this._prevStopper=n,n}},{key:"exec",value:function(){for(var e=arguments.length,r=Array(e),n=0;e>n;n++)r[n]=arguments[n];return this.$q.resolve(i(Object.getPrototypeOf(t.prototype),"exec",this).apply(this,r))}},{key:"ids",value:function(){for(var e=arguments.length,r=Array(e),n=0;e>n;n++)r[n]=arguments[n];return this.$q.resolve(i(Object.getPrototypeOf(t.prototype),"ids",this).apply(this,r))}},{key:"update",value:function(){for(var e=arguments.length,r=Array(e),n=0;e>n;n++)r[n]=arguments[n];return this.$q.resolve(i(Object.getPrototypeOf(t.prototype),"update",this).apply(this,r))}}]),t}(a);r.AngularCursorObservable=l,r["default"]=l},{"../CursorObservable":void 0}],3:[function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}var o=e("./AngularCollection"),u=n(o),i="undefined"!=typeof window&&window.angular?window.angular:e("angular"),a="undefined"!=typeof window&&window.Mars?window.Mars.Collection:e("../Collection")["default"];i.module("MarsDB",[]).provider("$collection",function(){this.defaultStorageManager=function(e){return a.defaultStorageManager(e),this},this.defaultIdGenerator=function(e){return a.defaultIdGenerator(e),this};var e={};this.$get=["$q",function(t){return function(r){var n=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];if(e[r]&&!n.noCache)return e[r];var o=new u["default"](r,n,t);return n.noCache||(e[r]=o),o}}]}),t["export"]="MarsDB"},{"../Collection":void 0,"./AngularCollection":1,angular:void 0}]},{},[3]); | ||
!function e(t,r,n){function o(i,a){if(!r[i]){if(!t[i]){var l="function"==typeof require&&require;if(!a&&l)return l(i,!0);if(u)return u(i,!0);var s=new Error("Cannot find module '"+i+"'");throw s.code="MODULE_NOT_FOUND",s}var c=r[i]={exports:{}};t[i][0].call(c.exports,function(e){var r=t[i][1][e];return o(r?r:e)},c,c.exports,e,t,r,n)}return r[i].exports}for(var u="function"==typeof require&&require,i=0;i<n.length;i++)o(n[i]);return o}({1:[function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(r,"__esModule",{value:!0});var u=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),i=e("./AngularCursorObservable"),a=n(i),l="undefined"!=typeof window&&window.Mars?window.Mars.Collection:e("../Collection")["default"],s=function(){function e(t,r,n){o(this,e),this.$q=n,this._collection=new l(t,r)}return u(e,[{key:"ensureIndex",value:function(){var e;return this.$q.resolve((e=this._collection).ensureIndex.apply(e,arguments))}},{key:"insert",value:function(){var e;return this.$q.resolve((e=this._collection).insert.apply(e,arguments))}},{key:"insertAll",value:function(){var e;return this.$q.resolve((e=this._collection).insertAll.apply(e,arguments))}},{key:"update",value:function(){var e;return this.$q.resolve((e=this._collection).update.apply(e,arguments))}},{key:"remove",value:function(){var e;return this.$q.resolve((e=this._collection).remove.apply(e,arguments))}},{key:"find",value:function(e){return new a["default"](this,e)}},{key:"findOne",value:function(){var e;return this.$q.resolve((e=this._collection).findOne.apply(e,arguments))}},{key:"count",value:function(){var e;return this.$q.resolve((e=this._collection).count.apply(e,arguments))}},{key:"ids",value:function(){var e;return this.$q.resolve((e=this._collection).ids.apply(e,arguments))}},{key:"modelName",get:function(){return this._collection.modelName}}]),e}();r.AngularCollection=s,r["default"]=s},{"../Collection":void 0,"./AngularCursorObservable":2}],2:[function(e,t,r){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var u=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),i=function(e,t,r){for(var n=!0;n;){var o=e,u=t,i=r;a=s=l=void 0,n=!1,null===o&&(o=Function.prototype);var a=Object.getOwnPropertyDescriptor(o,u);if(void 0!==a){if("value"in a)return a.value;var l=a.get;return void 0===l?void 0:l.call(i)}var s=Object.getPrototypeOf(o);if(null===s)return void 0;e=s,t=u,r=i,n=!0}},a="undefined"!=typeof window&&window.Mars?window.Mars.CursorObservable:e("../CursorObservable")["default"],l=function(e){function t(e,r){n(this,t),i(Object.getPrototypeOf(t.prototype),"constructor",this).call(this,e._collection,r),this.$q=e.$q}return o(t,e),u(t,[{key:"destroy",value:function(e){return e&&e._prevStopper&&e._prevStopper.stop(),this}},{key:"observe",value:function(e,r){var n=i(Object.getPrototypeOf(t.prototype),"observe",this).call(this,e);return r&&r.$on("$destroy",function(){n.stop()}),this._prevStopper=n,n}},{key:"exec",value:function(){for(var e=arguments.length,r=Array(e),n=0;e>n;n++)r[n]=arguments[n];return this.$q.resolve(i(Object.getPrototypeOf(t.prototype),"exec",this).apply(this,r))}},{key:"ids",value:function(){for(var e=arguments.length,r=Array(e),n=0;e>n;n++)r[n]=arguments[n];return this.$q.resolve(i(Object.getPrototypeOf(t.prototype),"ids",this).apply(this,r))}},{key:"update",value:function(){for(var e=arguments.length,r=Array(e),n=0;e>n;n++)r[n]=arguments[n];return this.$q.resolve(i(Object.getPrototypeOf(t.prototype),"update",this).apply(this,r))}},{key:"_prepareListener",value:function(e){var r=this,n=i(Object.getPrototypeOf(t.prototype),"_prepareListener",this).call(this,e);return function(){return r.$q.resolve(n.apply(void 0,arguments)).then(function(){})}}}]),t}(a);r.AngularCursorObservable=l,r["default"]=l},{"../CursorObservable":void 0}],3:[function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}var o=e("./AngularCollection"),u=n(o),i="undefined"!=typeof window&&window.angular?window.angular:e("angular"),a="undefined"!=typeof window&&window.Mars?window.Mars.Collection:e("../Collection")["default"];i.module("MarsDB",[]).provider("$collection",function(){this.defaultStorageManager=function(e){return a.defaultStorageManager(e),this},this.defaultIdGenerator=function(e){return a.defaultIdGenerator(e),this};var e={};this.$get=["$q",function(t){return function(r){var n=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];if(e[r]&&!n.noCache)return e[r];var o=new u["default"](r,n,t);return n.noCache||(e[r]=o),o}}]}),t["export"]="MarsDB"},{"../Collection":void 0,"./AngularCollection":1,angular:void 0}]},{},[3]); |
@@ -43,2 +43,3 @@ 'use strict'; | ||
} | ||
return this; | ||
} | ||
@@ -96,2 +97,12 @@ | ||
} | ||
}, { | ||
key: '_prepareListener', | ||
value: function _prepareListener(listener) { | ||
var _this = this; | ||
var preparedFn = _get(Object.getPrototypeOf(AngularCursorObservable.prototype), '_prepareListener', this).call(this, listener); | ||
return function () { | ||
return _this.$q.resolve(preparedFn.apply(undefined, arguments)).then(function () {}); | ||
}; | ||
} | ||
}]); | ||
@@ -98,0 +109,0 @@ |
@@ -246,3 +246,3 @@ 'use strict'; | ||
if (!options.quiet) { | ||
this.emit('sync:update', query, options); | ||
this.emit('sync:update', query, modifier, options); | ||
} | ||
@@ -249,0 +249,0 @@ |
@@ -25,2 +25,10 @@ 'use strict'; | ||
var _lodashLangIsObject = require('lodash/lang/isObject'); | ||
var _lodashLangIsObject2 = _interopRequireDefault(_lodashLangIsObject); | ||
var _lodashLangToArray = require('lodash/lang/toArray'); | ||
var _lodashLangToArray2 = _interopRequireDefault(_lodashLangToArray); | ||
var _eventemitter3 = require('eventemitter3'); | ||
@@ -57,3 +65,5 @@ | ||
Reduce: null, | ||
Join: null | ||
Join: null, | ||
JoinEach: null, | ||
JoinAll: null | ||
}); | ||
@@ -73,15 +83,20 @@ | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.Join, function (docs, pipeObj, cursor) { | ||
return Promise.all(docs.map(function (x) { | ||
var res = pipeObj.value(x); | ||
if (cursor._observing && res && res.__onceJustUpdated) { | ||
(0, _invariant2['default'])(!res.__haveListeners, 'joins(...): for using observable joins `observe` must be called without arguments'); | ||
res.__onceJustUpdated(function () { | ||
res.stop(); | ||
cursor.update(); | ||
}); | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinEach](docs, pipeObj, cursor); | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.JoinEach, function (docs, pipeObj, cursor) { | ||
return Promise.all((0, _lodashLangToArray2['default'])(docs).map(function (x) { | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinAll](x, pipeObj, cursor); | ||
})); | ||
}), _defineProperty(_PIPELINE_PROCESSORS, PIPELINE_TYPE.JoinAll, function (docs, pipeObj, cursor) { | ||
var res = pipeObj.value(docs); | ||
if ((0, _lodashLangIsObject2['default'])(res) && res.then) { | ||
if (res.parent) { | ||
res.parent(cursor); | ||
cursor.once('stopped', res.stop); | ||
} | ||
return res; | ||
})); | ||
return res.then(function () { | ||
return docs; | ||
}); | ||
} else { | ||
return docs; | ||
} | ||
}), _PIPELINE_PROCESSORS); | ||
@@ -189,8 +204,21 @@ | ||
value: function join(joinFn) { | ||
(0, _invariant2['default'])(typeof joinFn === 'function', 'join(...): argument must be a function'); | ||
return this.joinEach(joinFn); | ||
} | ||
}, { | ||
key: 'joinEach', | ||
value: function joinEach(joinFn) { | ||
(0, _invariant2['default'])(typeof joinFn === 'function', 'joinEach(...): argument must be a function'); | ||
this.addPipeline(PIPELINE_TYPE.Join, joinFn); | ||
this.addPipeline(PIPELINE_TYPE.JoinEach, joinFn); | ||
return this; | ||
} | ||
}, { | ||
key: 'joinAll', | ||
value: function joinAll(joinFn) { | ||
(0, _invariant2['default'])(typeof joinFn === 'function', 'joinAll(...): argument must be a function'); | ||
this.addPipeline(PIPELINE_TYPE.JoinAll, joinFn); | ||
return this; | ||
} | ||
}, { | ||
key: 'addPipeline', | ||
@@ -197,0 +225,0 @@ value: function addPipeline(type, val) { |
@@ -9,3 +9,3 @@ 'use strict'; | ||
var _get = function get(_x2, _x3, _x4) { var _again = true; _function: while (_again) { var object = _x2, property = _x3, receiver = _x4; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x2 = parent; _x3 = property; _x4 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; | ||
@@ -94,8 +94,4 @@ exports.debounce = debounce; | ||
// Listen for changes of the cursor | ||
this._observing = true; | ||
this._haveListeners = this._haveListeners || !!listener; | ||
if (listener) { | ||
this.on('update', listener); | ||
} | ||
listener = this._prepareListener(listener); | ||
this.on('update', listener); | ||
@@ -111,3 +107,2 @@ // Make new wrapper for make possible to observe | ||
var firstUpdatePromise = this.update(true); | ||
var stopper = function () { | ||
@@ -117,13 +112,13 @@ _this.db.removeListener('insert', updateWrapper); | ||
_this.db.removeListener('remove', updateWrapper); | ||
if (listener) { | ||
_this.removeListener('update', listener); | ||
} | ||
_this.removeListener('update', listener); | ||
_this.emit('stopped'); | ||
}; | ||
var parentSetter = function (cursor) { | ||
_this._parentCursor = cursor; | ||
}; | ||
var createStoppablePromise = function (currPromise) { | ||
// __onceUpdate is used when we do not need to know | ||
// a new result of a cursor, but just need to know | ||
// absout some changes happen. Used in observable joins. | ||
return { | ||
__haveListeners: _this._haveListeners, // must be false | ||
__onceJustUpdated: _this.once.bind(_this, 'justUpdated'), | ||
parent: parentSetter, | ||
stop: stopper, | ||
@@ -136,2 +131,3 @@ then: function (successFn, failFn) { | ||
var firstUpdatePromise = this.update(true); | ||
return createStoppablePromise(firstUpdatePromise); | ||
@@ -153,24 +149,26 @@ } | ||
if (!this._haveListeners && !firstRun) { | ||
// Fast path for just notifying about some changes | ||
// happen when no listeners to `observe` provided | ||
// and it's not a first run (initial data). | ||
// It's used in observable joins | ||
this.emit('justUpdated', null, firstRun); | ||
return Promise.resolve(); | ||
} else { | ||
return this.exec().then(function (result) { | ||
_this2._latestResult = result; | ||
_this2._latestIds = new Set(result.map(function (x) { | ||
return x._id; | ||
})); | ||
_this2.emit('update', result, firstRun); | ||
return result; | ||
}); | ||
} | ||
return this.exec().then(function (result) { | ||
_this2._latestResult = result; | ||
_this2._latestIds = new Set(result.map(function (x) { | ||
return x._id; | ||
})); | ||
_this2._propagateUpdate(firstRun); | ||
return result; | ||
}); | ||
} | ||
// TODO improve performance, we should be smarter | ||
// and don't emit fully request update in many | ||
// cases | ||
/** | ||
* Consider to update a query by given newDoc and oldDoc, | ||
* received form insert/udpate/remove oparation. | ||
* Should make a decision as smart as possible. | ||
* (Don't update a cursor if it does not change a result | ||
* of a cursor) | ||
* | ||
* TODO improve performance, we should be smarter | ||
* and don't emit fully request update in many | ||
* cases | ||
* | ||
* @param {Object} newDoc | ||
* @param {Object} oldDoc | ||
*/ | ||
}, { | ||
@@ -187,2 +185,33 @@ key: 'maybeUpdate', | ||
} | ||
/** | ||
* Preapare a listener of updates. By default it just debounce | ||
* it a little for no useless updates when update propagated | ||
* from children cursors. | ||
* @param {Function} listener | ||
* @return {Promise} | ||
*/ | ||
}, { | ||
key: '_prepareListener', | ||
value: function _prepareListener(listener) { | ||
// Debounce listener a little for update propagation | ||
// when joins updated | ||
return debounce(listener, 0, 0); | ||
} | ||
/** | ||
* Emits an update event with current result of a cursor | ||
* and call this method on parent cursor if it exists | ||
* and if it is not first run of update. | ||
*/ | ||
}, { | ||
key: '_propagateUpdate', | ||
value: function _propagateUpdate() { | ||
var firstRun = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; | ||
this.emit('update', this._latestResult, firstRun); | ||
if (!firstRun && this._parentCursor && this._parentCursor._propagateUpdate) { | ||
this._parentCursor._propagateUpdate(false); | ||
} | ||
} | ||
}]); | ||
@@ -189,0 +218,0 @@ |
@@ -24,2 +24,3 @@ const CursorObservable = typeof window !== 'undefined' && window.Mars | ||
} | ||
return this; | ||
} | ||
@@ -60,4 +61,9 @@ | ||
} | ||
_prepareListener(listener) { | ||
const preparedFn = super._prepareListener(listener); | ||
return (...args) => this.$q.resolve(preparedFn(...args)).then(() => {}); | ||
} | ||
} | ||
export default AngularCursorObservable; |
@@ -196,3 +196,3 @@ import EventEmitter from 'eventemitter3'; | ||
if (!options.quiet) { | ||
this.emit('sync:update', query, options); | ||
this.emit('sync:update', query, modifier, options); | ||
} | ||
@@ -199,0 +199,0 @@ |
import _each from 'lodash/collection/each'; | ||
import _isObject from 'lodash/lang/isObject'; | ||
import _toArray from 'lodash/lang/toArray'; | ||
import EventEmitter from 'eventemitter3'; | ||
@@ -19,2 +20,4 @@ import invariant from 'invariant'; | ||
Join: null, | ||
JoinEach: null, | ||
JoinAll: null, | ||
}); | ||
@@ -39,14 +42,20 @@ | ||
[PIPELINE_TYPE.Join]: (docs, pipeObj, cursor) => { | ||
return Promise.all(docs.map(x => { | ||
const res = pipeObj.value(x); | ||
if (_isObject(res) && res.then) { | ||
if (res.parent) { | ||
res.parent(cursor); | ||
cursor.once('stopped', res.stop); | ||
} | ||
return res.then(() => x); | ||
} else { | ||
return x; | ||
return PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinEach](docs, pipeObj, cursor); | ||
}, | ||
[PIPELINE_TYPE.JoinEach]: (docs, pipeObj, cursor) => { | ||
return Promise.all(_toArray(docs).map( | ||
(x) => PIPELINE_PROCESSORS[PIPELINE_TYPE.JoinAll](x, pipeObj, cursor) | ||
)); | ||
}, | ||
[PIPELINE_TYPE.JoinAll]: (docs, pipeObj, cursor) => { | ||
const res = pipeObj.value(docs); | ||
if (_isObject(res) && res.then) { | ||
if (res.parent) { | ||
res.parent(cursor); | ||
cursor.once('stopped', res.stop); | ||
} | ||
})); | ||
return res.then(() => docs); | ||
} else { | ||
return docs; | ||
} | ||
}, | ||
@@ -167,11 +176,25 @@ }; | ||
join(joinFn) { | ||
return this.joinEach(joinFn); | ||
} | ||
joinEach(joinFn) { | ||
invariant( | ||
typeof joinFn === 'function', | ||
'join(...): argument must be a function' | ||
'joinEach(...): argument must be a function' | ||
); | ||
this.addPipeline(PIPELINE_TYPE.Join, joinFn); | ||
this.addPipeline(PIPELINE_TYPE.JoinEach, joinFn); | ||
return this; | ||
} | ||
joinAll(joinFn) { | ||
invariant( | ||
typeof joinFn === 'function', | ||
'joinAll(...): argument must be a function' | ||
); | ||
this.addPipeline(PIPELINE_TYPE.JoinAll, joinFn); | ||
return this; | ||
} | ||
addPipeline(type, val, ...args) { | ||
@@ -178,0 +201,0 @@ this._ensureNotExecuting(); |
@@ -49,5 +49,3 @@ import Cursor from './Cursor'; | ||
observe(listener) { | ||
// Debounce listener a little for update propagation | ||
// when joins updated | ||
listener = debounce(listener, 0, 0); | ||
listener = this._prepareListener(listener); | ||
this.on('update', listener); | ||
@@ -62,3 +60,2 @@ | ||
const firstUpdatePromise = this.update(true); | ||
const stopper = () => { | ||
@@ -71,5 +68,7 @@ this.db.removeListener('insert', updateWrapper); | ||
}; | ||
const parentSetter = (cursor) => { | ||
this._parentCursor = cursor; | ||
}; | ||
const createStoppablePromise = (currPromise) => { | ||
@@ -85,2 +84,3 @@ return { | ||
const firstUpdatePromise = this.update(true); | ||
return createStoppablePromise(firstUpdatePromise); | ||
@@ -99,9 +99,3 @@ } | ||
this._latestIds = new Set(result.map(x => x._id)); | ||
this.emit('update', result, firstRun); | ||
if (this._parentCursor && !firstRun) { | ||
const parentResult = this._parentCursor._latestResult; | ||
this._parentCursor.emit('update', parentResult, false); | ||
} | ||
this._propagateUpdate(firstRun); | ||
return result; | ||
@@ -111,5 +105,16 @@ }); | ||
// TODO improve performance, we should be smarter | ||
// and don't emit fully request update in many | ||
// cases | ||
/** | ||
* Consider to update a query by given newDoc and oldDoc, | ||
* received form insert/udpate/remove oparation. | ||
* Should make a decision as smart as possible. | ||
* (Don't update a cursor if it does not change a result | ||
* of a cursor) | ||
* | ||
* TODO improve performance, we should be smarter | ||
* and don't emit fully request update in many | ||
* cases | ||
* | ||
* @param {Object} newDoc | ||
* @param {Object} oldDoc | ||
*/ | ||
maybeUpdate(newDoc, oldDoc) { | ||
@@ -129,2 +134,27 @@ const removedFromResult = ( | ||
} | ||
/** | ||
* Preapare a listener of updates. By default it just debounce | ||
* it a little for no useless updates when update propagated | ||
* from children cursors. | ||
* @param {Function} listener | ||
* @return {Promise} | ||
*/ | ||
_prepareListener(listener) { | ||
// Debounce listener a little for update propagation | ||
// when joins updated | ||
return debounce(listener, 0, 0); | ||
} | ||
/** | ||
* Emits an update event with current result of a cursor | ||
* and call this method on parent cursor if it exists | ||
* and if it is not first run of update. | ||
*/ | ||
_propagateUpdate(firstRun = false) { | ||
this.emit('update', this._latestResult, firstRun); | ||
if (!firstRun && this._parentCursor && this._parentCursor._propagateUpdate) { | ||
this._parentCursor._propagateUpdate(false); | ||
} | ||
} | ||
} | ||
@@ -131,0 +161,0 @@ |
{ | ||
"name": "marsdb", | ||
"version": "0.3.5", | ||
"version": "0.3.6", | ||
"author": { | ||
@@ -5,0 +5,0 @@ "name": "Artem Artemev", |
@@ -282,3 +282,3 @@ import Collection from '../../lib/Collection'; | ||
describe('#join', function () { | ||
describe('#joinEach', function () { | ||
it('should join by function with promises', function () { | ||
@@ -290,3 +290,2 @@ const cursor = new Cursor(db); | ||
d.groupObjs = result; | ||
return d; | ||
}); | ||
@@ -309,3 +308,24 @@ }); | ||
describe('#joinAll', function () { | ||
it('should join by function with promises', function () { | ||
return db.find({b: {$in: [1,2,3]}}).sort(['b']).joinAll(docs => { | ||
docs.should.have.length(3); | ||
return db.find({g: docs[0].g}).exec().then((result) => { | ||
docs.forEach(d => d.groupObjs = result); | ||
}); | ||
}).exec().then((docs) => { | ||
docs.should.have.length(3); | ||
docs[0].groupObjs.should.have.length(4); | ||
docs[1].groupObjs.should.have.length(4); | ||
docs[2].groupObjs.should.have.length(4); | ||
}); | ||
}); | ||
it('should throw an error if join is not a function', function () { | ||
const cursor = new Cursor(db); | ||
(() => cursor.joinAll(123)).should.throw(Error); | ||
}); | ||
}); | ||
describe('#ids', function () { | ||
@@ -312,0 +332,0 @@ it('should return list of ids without pipeline processing', function () { |
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
1060804
24749