mobdb
Version:
MarsDB is a lightweight client-side MongoDB-like database, Promise based, written in ES6
1,529 lines (1,263 loc) • 582 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Mars = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
'use strict';
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
};
}();
var _eventemitter = require('eventemitter3');
var _eventemitter2 = _interopRequireDefault(_eventemitter);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}return call && ((typeof call === "undefined" ? "undefined" : _typeof(call)) === "object" || typeof call === "function") ? call : self;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === "undefined" ? "undefined" : _typeof(superClass)));
}subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
/**
* Extension of a regular EventEmitter that provides a method
* that returns a Promise then resolved when all listeners of the event
* will be resolved.
*/
/* istanbul ignore next */
var AsyncEventEmitter = function (_EventEmitter) {
_inherits(AsyncEventEmitter, _EventEmitter);
function AsyncEventEmitter() {
_classCallCheck(this, AsyncEventEmitter);
return _possibleConstructorReturn(this, (AsyncEventEmitter.__proto__ || Object.getPrototypeOf(AsyncEventEmitter)).apply(this, arguments));
}
_createClass(AsyncEventEmitter, [{
key: 'emitAsync',
/**
* Emit an event and return a Promise that will be resolved
* when all listeren's Promises will be resolved.
* @param {String} event
* @return {Promise}
*/
value: function emitAsync(event, a1, a2, a3, a4, a5) {
var prefix = _eventemitter2.default.prefixed;
var evt = prefix ? prefix + event : event;
if (!this._events || !this._events[evt]) {
return Promise.resolve();
}
var i = void 0;
var listeners = this._events[evt];
var len = arguments.length;
var args = void 0;
if ('function' === typeof listeners.fn) {
if (listeners.once) {
this.removeListener(event, listeners.fn, undefined, true);
}
switch (len) {
case 1:
return Promise.resolve(listeners.fn.call(listeners.context));
case 2:
return Promise.resolve(listeners.fn.call(listeners.context, a1));
case 3:
return Promise.resolve(listeners.fn.call(listeners.context, a1, a2));
case 4:
return Promise.resolve(listeners.fn.call(listeners.context, a1, a2, a3));
case 5:
return Promise.resolve(listeners.fn.call(listeners.context, a1, a2, a3, a4));
case 6:
return Promise.resolve(listeners.fn.call(listeners.context, a1, a2, a3, a4, a5));
}
for (i = 1, args = new Array(len - 1); i < len; i++) {
args[i - 1] = arguments[i];
}
return Promise.resolve(listeners.fn.apply(listeners.context, args));
} else {
var promises = [];
var length = listeners.length;
var j = void 0;
for (i = 0; i < length; i++) {
if (listeners[i].once) {
this.removeListener(event, listeners[i].fn, undefined, true);
}
switch (len) {
case 1:
promises.push(Promise.resolve(listeners[i].fn.call(listeners[i].context)));break;
case 2:
promises.push(Promise.resolve(listeners[i].fn.call(listeners[i].context, a1)));break;
case 3:
promises.push(Promise.resolve(listeners[i].fn.call(listeners[i].context, a1, a2)));break;
default:
if (!args) {
for (j = 1, args = new Array(len - 1); j < len; j++) {
args[j - 1] = arguments[j];
}
}
promises.push(Promise.resolve(listeners[i].fn.apply(listeners[i].context, args)));
}
}
return Promise.all(promises);
}
}
}]);
return AsyncEventEmitter;
}(_eventemitter2.default);
exports.default = AsyncEventEmitter;
},{"eventemitter3":35}],2:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
/**
* Based on Meteor's Base64 package.
* Rewrite with ES6 and better formated for passing
* linter
*/
var BASE_64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var BASE_64_VALS = {};
(function setupBase64Vals() {
for (var j = 0; j < BASE_64_CHARS.length; j++) {
BASE_64_VALS[BASE_64_CHARS.charAt(j)] = j;
}
})();
var getChar = function getChar(val) {
return BASE_64_CHARS.charAt(val);
};
var getVal = function getVal(ch) {
if (ch === '=') {
return -1;
}
return BASE_64_VALS[ch];
};
// Base 64 encoding
var Base64 = exports.Base64 = function () {
function Base64() {
_classCallCheck(this, Base64);
}
_createClass(Base64, [{
key: 'encode',
value: function encode(array) {
if (typeof array === 'string') {
var str = array;
array = this.newBinary(str.length);
for (var i = 0; i < str.length; i++) {
var ch = str.charCodeAt(i);
if (ch > 0xFF) {
throw new Error('Not ascii. Base64.encode can only take ascii strings.');
}
array[i] = ch;
}
}
var answer = [];
var a = null;
var b = null;
var c = null;
var d = null;
for (var _i = 0; _i < array.length; _i++) {
switch (_i % 3) {
case 0:
a = array[_i] >> 2 & 0x3F;
b = (array[_i] & 0x03) << 4;
break;
case 1:
b |= array[_i] >> 4 & 0xF;
c = (array[_i] & 0xF) << 2;
break;
case 2:
c |= array[_i] >> 6 & 0x03;
d = array[_i] & 0x3F;
answer.push(getChar(a));
answer.push(getChar(b));
answer.push(getChar(c));
answer.push(getChar(d));
a = null;
b = null;
c = null;
d = null;
break;
}
}
if (a != null) {
answer.push(getChar(a));
answer.push(getChar(b));
if (c == null) {
answer.push('=');
} else {
answer.push(getChar(c));
}
if (d == null) {
answer.push('=');
}
}
return answer.join('');
}
}, {
key: 'decode',
value: function decode(str) {
var len = Math.floor(str.length * 3 / 4);
if (str.charAt(str.length - 1) == '=') {
len--;
if (str.charAt(str.length - 2) == '=') {
len--;
}
}
var arr = this.newBinary(len);
var one = null;
var two = null;
var three = null;
var j = 0;
for (var i = 0; i < str.length; i++) {
var c = str.charAt(i);
var v = getVal(c);
switch (i % 4) {
case 0:
if (v < 0) {
throw new Error('invalid base64 string');
}
one = v << 2;
break;
case 1:
if (v < 0) {
throw new Error('invalid base64 string');
}
one |= v >> 4;
arr[j++] = one;
two = (v & 0x0F) << 4;
break;
case 2:
if (v >= 0) {
two |= v >> 2;
arr[j++] = two;
three = (v & 0x03) << 6;
}
break;
case 3:
if (v >= 0) {
arr[j++] = three | v;
}
break;
}
}
return arr;
}
}, {
key: 'newBinary',
value: function newBinary(len) {
if (typeof Uint8Array === 'undefined' || typeof ArrayBuffer === 'undefined') {
var ret = [];
for (var i = 0; i < len; i++) {
ret.push(0);
}
ret.$Uint8ArrayPolyfill = true;
return ret;
}
return new Uint8Array(new ArrayBuffer(len));
}
}]);
return Base64;
}();
exports.default = new Base64();
},{}],3:[function(require,module,exports){
'use strict';
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Collection = undefined;
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
};
}();
exports._resetStartup = _resetStartup;
exports._warnIfAlreadyStarted = _warnIfAlreadyStarted;
var _map2 = require('fast.js/map');
var _map3 = _interopRequireDefault(_map2);
var _forEach = require('fast.js/forEach');
var _forEach2 = _interopRequireDefault(_forEach);
var _checkTypes = require('check-types');
var _checkTypes2 = _interopRequireDefault(_checkTypes);
var _AsyncEventEmitter = require('./AsyncEventEmitter');
var _AsyncEventEmitter2 = _interopRequireDefault(_AsyncEventEmitter);
var _IndexManager = require('./IndexManager');
var _IndexManager2 = _interopRequireDefault(_IndexManager);
var _StorageManager = require('./StorageManager');
var _StorageManager2 = _interopRequireDefault(_StorageManager);
var _CollectionDelegate = require('./CollectionDelegate');
var _CollectionDelegate2 = _interopRequireDefault(_CollectionDelegate);
var _CursorObservable = require('./CursorObservable');
var _CursorObservable2 = _interopRequireDefault(_CursorObservable);
var _ShortIdGenerator = require('./ShortIdGenerator');
var _ShortIdGenerator2 = _interopRequireDefault(_ShortIdGenerator);
var _EJSON = require('./EJSON');
var _EJSON2 = _interopRequireDefault(_EJSON);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}return call && ((typeof call === "undefined" ? "undefined" : _typeof(call)) === "object" || typeof call === "function") ? call : self;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === "undefined" ? "undefined" : _typeof(superClass)));
}subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
// Defaults
var _defaultCursor = _CursorObservable2.default;
var _defaultDelegate = _CollectionDelegate2.default;
var _defaultStorageManager = _StorageManager2.default;
var _defaultIndexManager = _IndexManager2.default;
var _defaultIdGenerator = _ShortIdGenerator2.default;
// Startup all init dependent functions on
// the second execution cycle
var _startedUp = false;
var _startUpQueue = [];
var _startUpId = 0;
// Internals
function _resetStartup() {
var waitMs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
_startUpId += 1;
_startUpQueue = [];
_startedUp = false;
var currStartId = _startUpId;
setTimeout(function () {
if (currStartId === _startUpId) {
_startedUp = true;
(0, _forEach2.default)(_startUpQueue, function (fn) {
return fn();
});
_startUpQueue = [];
}
}, waitMs);
}
function _warnIfAlreadyStarted() {
if (_startedUp) {
console.warn('You are trying to change some default of the Collection,' + 'but all collections is already initialized. It may be happened ' + 'because you are trying to configure Collection not at first ' + 'execution cycle of main script. Please consider to move all ' + 'configuration to first execution cycle.');
}
}
// Initiate startup
_resetStartup();
/**
* Core class of the database.
* It delegates almost all it's methods to managers
* and emits events for live queries and other cuctomisation.
*/
var Collection = exports.Collection = function (_EventEmitter) {
_inherits(Collection, _EventEmitter);
function Collection(name) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Collection);
var _this = _possibleConstructorReturn(this, (Collection.__proto__ || Object.getPrototypeOf(Collection)).call(this));
_this.options = options;
_this._modelName = name;
// Shorthand for defining in-memory collection
if (options.inMemory) {
options.cursorClass = options.cursorClass || _CursorObservable2.default;
options.delegate = options.delegate || _CollectionDelegate2.default;
options.storageManager = options.storageManager || _StorageManager2.default;
options.indexManager = options.indexManager || _IndexManager2.default;
options.idGenerator = options.idGenerator || _ShortIdGenerator2.default;
}
// Initialize collection only after configuration done
Collection.startup(function () {
return _this._lazyInitCollection();
});
return _this;
}
_createClass(Collection, [{
key: 'create',
/**
* Factory for creating an object of the model
* @param {String|Object} raw
* @return {Object}
*/
value: function create(raw) {
return _checkTypes2.default.string(raw) ? _EJSON2.default.parse(raw) : raw;
}
/**
* Insert a document into the model and
* emit `synd:insert` event (if not quiet).
* @param {Object} doc
* @param {Boolean} quiet
* @return {Promise}
*/
}, {
key: 'insert',
value: function insert(doc) {
var _this2 = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
this._lazyInitCollection();
var randomId = this.idGenerator(this.modelName);
doc = this.create(doc);
doc._id = doc._id || randomId.value;
this.emit('beforeInsert', doc, randomId);
if (!options.quiet) {
this.emit('sync:insert', doc, randomId);
}
return this.delegate.insert(doc, options, randomId).then(function (docId) {
_this2.emit('insert', doc, null, randomId);
return docId;
});
}
/**
* Just a sugar for mulpitle inserts. Wrap all inserts
* with a single Promise and return it.
* @param {Array} docs
* @param {Object} options
* @return {Promise}
*/
}, {
key: 'insertAll',
value: function insertAll(docs) {
var _this3 = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return Promise.all((0, _map3.default)(docs, function (d) {
return _this3.insert(d, options);
}));
}
/**
* Remove an object (or objects with options.multi)
* from the model.
* @param {Object} query
* @param {Object} options
* @param {Boolean} quiet
* @return {Promise}
*/
}, {
key: 'remove',
value: function remove(query) {
var _this4 = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
this._lazyInitCollection();
this.emit('beforeRemove', query, options);
if (!options.quiet) {
this.emit('sync:remove', query, options);
}
return this.delegate.remove(query, options).then(function (removedDocs) {
(0, _forEach2.default)(removedDocs, function (d) {
return _this4.emit('remove', null, d);
});
return removedDocs;
});
}
/**
* Remove an object (or objects with options.multi)
* from the model.
* NOTE: `upsert` is not supported, only `multi`
* @param {Object} query
* @param {Object} options
* @param {Boolean} quiet
* @return {Promise}
*/
}, {
key: 'update',
value: function update(query, modifier) {
var _this5 = this;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
this._lazyInitCollection();
this.emit('beforeUpdate', query, modifier, options);
if (!options.quiet) {
this.emit('sync:update', query, modifier, options);
}
return this.delegate.update(query, modifier, options).then(function (res) {
(0, _forEach2.default)(res.updated, function (d, i) {
_this5.emit('update', d, res.original[i]);
});
return res;
});
}
/**
* Make a cursor with given query and return.
* By default all documents clonned before passed
* to pipeline functions. By setting `options.noClone`
* to `true` clonning may be disabled (for your own risk)
* @param {Object} query
* @param {Number} options.noClone
* @return {CursorObservable}
*/
}, {
key: 'find',
value: function find(query) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
this._lazyInitCollection();
return this.delegate.find(query, options);
}
/**
* Finds one object by given query and sort object.
* Return a promise that resolved with a document object
* or with undefined if no object found.
* @param {Object} query
* @param {Object} sortObj
* @return {CursorObservable}
*/
}, {
key: 'findOne',
value: function findOne(query) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
this._lazyInitCollection();
return this.delegate.findOne(query, options);
}
/**
* Returns a number of matched by query objects. It's
* based on `ids` function and uses only indexes.
* In this case it's much more faster then doing
* `find().length`, because it does not going to the
* storage.
* @param {Object} query
* @return {CursorObservable}
*/
}, {
key: 'count',
value: function count(query) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
this._lazyInitCollection();
return this.delegate.count(query, options);
}
/**
* Return a list of ids by given query. Uses only
* indexes.
* @param {Object} query
* @return {CursorObservable}
*/
}, {
key: 'ids',
value: function ids(query) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
this._lazyInitCollection();
return this.delegate.ids(query, options);
}
/**
* Initialize collection managers by stored options. It is
* used for solving execution order problem of Collection
* configuration functions.
*/
}, {
key: '_lazyInitCollection',
value: function _lazyInitCollection() {
if (!this._initialized) {
this._initialized = true;
var options = this.options;
var storageManagerClass = options.storageManager || _defaultStorageManager;
var delegateClass = options.delegate || _defaultDelegate;
var indexManagerClass = options.indexManager || _defaultIndexManager;
this.idGenerator = options.idGenerator || _defaultIdGenerator;
this.cursorClass = options.cursorClass || _defaultCursor;
this.indexManager = new indexManagerClass(this, options);
this.storageManager = new storageManagerClass(this, options);
this.delegate = new delegateClass(this, options);
}
}
/**
* Wihout arguments it returns current default storage manager.
* If arguments provided, then first argument will be set as default
* storage manager and all collections, who uses default storage manager,
* will be upgraded to a new strage manager.
* @return {undefined|Class}
*/
}, {
key: 'modelName',
get: function get() {
return this._modelName;
}
}, {
key: 'indexes',
get: function get() {
this._lazyInitCollection();
return this.indexManager.indexes;
}
}, {
key: 'storage',
get: function get() {
this._lazyInitCollection();
return this.storageManager;
}
}], [{
key: 'defaultCursor',
value: function defaultCursor() {
if (arguments.length > 0) {
_warnIfAlreadyStarted();
_defaultCursor = arguments[0];
} else {
return _defaultCursor;
}
}
/**
* Wihout arguments it returns current default storage manager.
* If arguments provided, then first argument will be set as default
* storage manager and all collections, who uses default storage manager,
* will be upgraded to a new strage manager.
* @return {undefined|Class}
*/
}, {
key: 'defaultStorageManager',
value: function defaultStorageManager() {
if (arguments.length > 0) {
_warnIfAlreadyStarted();
_defaultStorageManager = arguments[0];
} else {
return _defaultStorageManager;
}
}
/**
* Wihout arguments it returns current default id generator.
* If arguments provided, then first argument will be set as default
* id generator and all collections, who uses default id generator,
* will be upgraded to a new id generator.
* @return {undefined|Class}
*/
}, {
key: 'defaultIdGenerator',
value: function defaultIdGenerator() {
if (arguments.length > 0) {
_warnIfAlreadyStarted();
_defaultIdGenerator = arguments[0];
} else {
return _defaultIdGenerator;
}
}
/**
* Wihout arguments it returns current default delegate class.
* If arguments provided, then first argument will be set as default
* delegate and all collections, who uses default delegate,
* will be upgraded to a new delegate.
* @return {undefined|Class}
*/
}, {
key: 'defaultDelegate',
value: function defaultDelegate() {
if (arguments.length > 0) {
_warnIfAlreadyStarted();
_defaultDelegate = arguments[0];
} else {
return _defaultDelegate;
}
}
/**
* Wihout arguments it returns current default index manager class.
* If arguments provided, then first argument will be set as default
* index manager and all collections, who uses default index manager,
* will be upgraded to a new index manager.
* @return {undefined|Class}
*/
}, {
key: 'defaultIndexManager',
value: function defaultIndexManager() {
if (arguments.length > 0) {
_warnIfAlreadyStarted();
_defaultIndexManager = arguments[0];
} else {
return _defaultIndexManager;
}
}
/**
* Execute some function after current execution cycle. For using fully
* configured collection.
* @param {Function} fn
*/
}, {
key: 'startup',
value: function startup(fn) {
if (_startedUp) {
fn();
} else {
_startUpQueue.push(fn);
}
}
}]);
return Collection;
}(_AsyncEventEmitter2.default);
exports.default = Collection;
},{"./AsyncEventEmitter":1,"./CollectionDelegate":4,"./CursorObservable":7,"./EJSON":14,"./IndexManager":15,"./ShortIdGenerator":19,"./StorageManager":20,"check-types":33,"fast.js/forEach":43,"fast.js/map":50}],4:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CollectionDelegate = undefined;
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
};
}();
var _map2 = require('fast.js/map');
var _map3 = _interopRequireDefault(_map2);
var _DocumentModifier = require('./DocumentModifier');
var _DocumentModifier2 = _interopRequireDefault(_DocumentModifier);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}return arr2;
} else {
return Array.from(arr);
}
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
/**
* Default collection delegate for working with a
* normal MarsDB approach – within a browser.
*/
var CollectionDelegate = exports.CollectionDelegate = function () {
function CollectionDelegate(db) {
_classCallCheck(this, CollectionDelegate);
this.db = db;
}
_createClass(CollectionDelegate, [{
key: 'insert',
value: function insert(doc) {
var _this = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var randomId = arguments[2];
return this.db.indexManager.indexDocument(doc).then(function () {
return _this.db.storageManager.persist(doc._id, doc).then(function () {
return doc._id;
});
});
}
}, {
key: 'remove',
value: function remove(query, _ref) {
var _this2 = this;
var _ref$sort = _ref.sort,
sort = _ref$sort === undefined ? { _id: 1 } : _ref$sort,
_ref$multi = _ref.multi,
multi = _ref$multi === undefined ? false : _ref$multi;
return this.find(query, { noClone: true }).sort(sort).then(function (docs) {
if (docs.length > 1 && !multi) {
docs = [docs[0]];
}
var removeStorgePromises = (0, _map3.default)(docs, function (d) {
return _this2.db.storageManager.delete(d._id);
});
var removeIndexPromises = (0, _map3.default)(docs, function (d) {
return _this2.db.indexManager.deindexDocument(d);
});
return Promise.all([].concat(_toConsumableArray(removeStorgePromises), _toConsumableArray(removeIndexPromises))).then(function () {
return docs;
});
});
}
}, {
key: 'update',
value: function update(query, modifier, _ref2) {
var _this3 = this;
var _ref2$sort = _ref2.sort,
sort = _ref2$sort === undefined ? { _id: 1 } : _ref2$sort,
_ref2$multi = _ref2.multi,
multi = _ref2$multi === undefined ? false : _ref2$multi,
_ref2$upsert = _ref2.upsert,
upsert = _ref2$upsert === undefined ? false : _ref2$upsert;
return this.find(query, { noClone: true }).sort(sort).then(function (docs) {
if (docs.length > 1 && !multi) {
docs = [docs[0]];
}
return new _DocumentModifier2.default(query).modify(docs, modifier, { upsert: upsert });
}).then(function (_ref3) {
var original = _ref3.original,
updated = _ref3.updated;
var updateStorgePromises = (0, _map3.default)(updated, function (d) {
return _this3.db.storageManager.persist(d._id, d);
});
var updateIndexPromises = (0, _map3.default)(updated, function (d, i) {
return _this3.db.indexManager.reindexDocument(original[i], d);
});
return Promise.all([].concat(_toConsumableArray(updateStorgePromises), _toConsumableArray(updateIndexPromises))).then(function () {
return {
modified: updated.length,
original: original,
updated: updated
};
});
});
}
}, {
key: 'find',
value: function find(query) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var cursorClass = this.db.cursorClass;
return new cursorClass(this.db, query, options);
}
}, {
key: 'findOne',
value: function findOne(query) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return this.find(query, options).aggregate(function (docs) {
return docs[0];
}).limit(1);
}
}, {
key: 'count',
value: function count(query) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
options.noClone = true;
return this.find(query, options).aggregate(function (docs) {
return docs.length;
});
}
}, {
key: 'ids',
value: function ids(query) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
options.noClone = true;
return this.find(query, options).map(function (doc) {
return doc._id;
});
}
}]);
return CollectionDelegate;
}();
exports.default = CollectionDelegate;
},{"./DocumentModifier":10,"fast.js/map":50}],5:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CollectionIndex = undefined;
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
};
}();
var _invariant = require('invariant');
var _invariant2 = _interopRequireDefault(_invariant);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var CollectionIndex = exports.CollectionIndex = function () {
function CollectionIndex() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, CollectionIndex);
(0, _invariant2.default)(options.fieldName, 'CollectionIndex(...): you must specify a "feildName" option');
(0, _invariant2.default)(!Array.isArray(options.fieldName), 'CollectionIndex(...): compound index is not supported yet');
this.fieldName = options.fieldName;
this.unique = options.unique || false;
this.sparse = options.sparse || false;
this.reset();
}
_createClass(CollectionIndex, [{
key: 'reset',
value: function reset() {
// TODO
}
}, {
key: 'insert',
value: function insert(doc) {
// TODO
}
}, {
key: 'remove',
value: function remove(doc) {
// TODO
}
}, {
key: 'update',
value: function update(oldDoc, newDoc) {
// TODO
}
}, {
key: 'getMatching',
value: function getMatching(value) {
// TODO
}
}, {
key: 'getBetweenBounds',
value: function getBetweenBounds(query) {
// TODO
}
}, {
key: 'getAll',
value: function getAll(options) {
// TODO
}
}]);
return CollectionIndex;
}();
exports.default = CollectionIndex;
},{"invariant":57}],6:[function(require,module,exports){
'use strict';
var _typeof2 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Cursor = exports.PIPELINE_PROCESSORS = undefined;
var _typeof = typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol" ? function (obj) {
return typeof obj === "undefined" ? "undefined" : _typeof2(obj);
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj === "undefined" ? "undefined" : _typeof2(obj);
};
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
};
}();
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}return target;
};
var _forEach = require('fast.js/forEach');
var _forEach2 = _interopRequireDefault(_forEach);
var _assign2 = require('fast.js/object/assign');
var _assign3 = _interopRequireDefault(_assign2);
var _keys2 = require('fast.js/object/keys');
var _keys3 = _interopRequireDefault(_keys2);
var _map2 = require('fast.js/map');
var _map3 = _interopRequireDefault(_map2);
var _AsyncEventEmitter2 = require('./AsyncEventEmitter');
var _AsyncEventEmitter3 = _interopRequireDefault(_AsyncEventEmitter2);
var _invariant = require('invariant');
var _invariant2 = _interopRequireDefault(_invariant);
var _DocumentRetriver = require('./DocumentRetriver');
var _DocumentRetriver2 = _interopRequireDefault(_DocumentRetriver);
var _DocumentMatcher = require('./DocumentMatcher');
var _DocumentMatcher2 = _interopRequireDefault(_DocumentMatcher);
var _DocumentSorter = require('./DocumentSorter');
var _DocumentSorter2 = _interopRequireDefault(_DocumentSorter);
var _DocumentProjector = require('./DocumentProjector');
var _DocumentProjector2 = _interopRequireDefault(_DocumentProjector);
var _EJSON = require('./EJSON');
var _EJSON2 = _interopRequireDefault(_EJSON);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}return call && ((typeof call === "undefined" ? "undefined" : _typeof2(call)) === "object" || typeof call === "function") ? call : self;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === "undefined" ? "undefined" : _typeof2(superClass)));
}subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
// UUID counter for all cursors
var _currentCursorId = 0;
// Pipeline processors map
var PIPELINE_PROCESSORS = exports.PIPELINE_PROCESSORS = _extends({}, require('./cursor-processors/filter'), require('./cursor-processors/sortFunc'), require('./cursor-processors/map'), require('./cursor-processors/aggregate'), require('./cursor-processors/reduce'), require('./cursor-processors/join'), require('./cursor-processors/joinEach'), require('./cursor-processors/joinAll'), require('./cursor-processors/joinObj'), require('./cursor-processors/ifNotEmpty'));
// Create basic cursor with pipeline methods
var BasicCursor = function (_AsyncEventEmitter) {
_inherits(BasicCursor, _AsyncEventEmitter);
function BasicCursor() {
_classCallCheck(this, BasicCursor);
return _possibleConstructorReturn(this, (BasicCursor.__proto__ || Object.getPrototypeOf(BasicCursor)).apply(this, arguments));
}
return BasicCursor;
}(_AsyncEventEmitter3.default);
(0, _forEach2.default)(PIPELINE_PROCESSORS, function (v, procName) {
BasicCursor.prototype[procName] = v.method;
});
/**
* Class for storing information about query
* and executing it. It also have a sugar like
* map/reduce, aggregation and others for making
* fully customizable response
*/
var Cursor = function (_BasicCursor) {
_inherits(Cursor, _BasicCursor);
function Cursor(db) {
var query = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
_classCallCheck(this, Cursor);
var _this2 = _possibleConstructorReturn(this, (Cursor.__proto__ || Object.getPrototypeOf(Cursor)).call(this));
_this2.db = db;
_this2.options = options;
_this2._id = _currentCursorId++;
_this2._query = query;
_this2._pipeline = [];
_this2._latestResult = null;
_this2._childrenCursors = {};
_this2._parentCursors = {};
_this2._ensureMatcherSorter();
return _this2;
}
_createClass(Cursor, [{
key: 'skip',
value: function skip(_skip) {
(0, _invariant2.default)(_skip >= 0 || typeof _skip === 'undefined', 'skip(...): skip must be a positive number');
this._skip = _skip;
return this;
}
}, {
key: 'limit',
value: function limit(_limit) {
(0, _invariant2.default)(_limit >= 0 || typeof _limit === 'undefined', 'limit(...): limit must be a positive number');
this._limit = _limit;
return this;
}
}, {
key: 'find',
value: function find(query) {
this._query = query;
this._ensureMatcherSorter();
return this;
}
}, {
key: 'project',
value: function project(projection) {
if (projection) {
this._projector = new _DocumentProjector2.default(projection);
} else {
this._projector = null;
}
return this;
}
}, {
key: 'sort',
value: function sort(sortObj) {
(0, _invariant2.default)((typeof sortObj === 'undefined' ? 'undefined' : _typeof(sortObj)) === 'object' || typeof sortObj === 'undefined' || Array.isArray(sortObj), 'sort(...): argument must be an object');
this._sort = sortObj;
this._ensureMatcherSorter();
return this;
}
}, {
key: 'exec',
value: function exec() {
var _this3 = this;
this.emit('beforeExecute');
return this._createCursorPromise(this._doExecute().then(function (result) {
_this3._latestResult = result;
return result;
}));
}
}, {
key: 'then',
value: function then(resolve, reject) {
return this.exec().then(resolve, reject);
}
}, {
key: '_addPipeline',
value: function _addPipeline(type, val) {
(0, _invariant2.default)(type && PIPELINE_PROCESSORS[type], 'Unknown pipeline processor type %s', type);
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}
this._pipeline.push({
type: type,
value: val,
args: args || []
});
return this;
}
}, {
key: '_processPipeline',
value: function _processPipeline(docs) {
var _this4 = this;
var i = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var pipeObj = this._pipeline[i];
if (!pipeObj) {
return Promise.resolve(docs);
} else {
return Promise.resolve(PIPELINE_PROCESSORS[pipeObj.type].process(docs, pipeObj, this)).then(function (result) {
if (result === '___[STOP]___') {
return result;
} else {
return _this4._processPipeline(result, i + 1);
}
});
}
}
}, {
key: '_doExecute',
value: function _doExecute() {
var _this5 = this;
return this._matchObjects().then(function (docs) {
var clonned = void 0;
if (_this5.options.noClone) {
clonned = docs;
} else {
if (!_this5._projector) {
clonned = (0, _map3.default)(docs, function (doc) {
return _EJSON2.default.clone(doc);
});
} else {
clonned = _this5._projector.project(docs);
}
}
return _this5._processPipeline(clonned);
});
}
}, {
key: '_matchObjects',
value: function _matchObjects() {
var _this6 = this;
var withFastLimit = this._limit && !this._skip && !this._sorter;
var retrOpts = withFastLimit ? { limit: this._limit } : {};
var queryFilter = function queryFilter(doc) {
return doc && _this6._matcher.documentMatches(doc).result;
};
return new _DocumentRetriver2.default(this.db).retriveForQeury(this._query, queryFilter, retrOpts).then(function (results) {
if (withFastLimit) {
return results;
}
if (_this6._sorter) {
var comparator = _this6._sorter.getComparator();
results.sort(comparator);
}
var skip = _this6._skip || 0;
var limit = _this6._limit || results.length;
return results.slice(skip, limit + skip);
});
}
}, {
key: '_ensureMatcherSorter',
value: function _ensureMatcherSorter() {
this._sorter = undefined;
this._matcher = new _DocumentMatcher2.default(this._query || {});
if (this._matcher.hasGeoQuery || this._sort) {
this._sorter = new _DocumentSorter2.default(this._sort || [], { matcher: this._matcher });
}
}
}, {
key: '_trackChildCursorPromise',
value: function _trackChildCursorPromise(childCursorPromise) {
var _this7 = this;
var childCursor = childCursorPromise.cursor;
this._childrenCursors[childCursor._id] = childCursor;
childCursor._parentCursors[this._id] = this;
this.once('beforeExecute', function () {
delete _this7._childrenCursors[childCursor._id];
delete childCursor._parentCursors[_this7._id];
if ((0, _keys3.default)(childCursor._parentCursors).length === 0) {
childCursor.emit('beforeExecute');
}
});
}
}, {
key: '_createCursorPromise',
value: function _createCursorPromise(promise) {
var _this8 = this;
var mixin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return (0, _assign3.default)({
cursor: this,
then: function then(successFn, failFn) {
return _this8._createCursorPromise(promise.then(successFn, failFn), mixin);
}
}, mixin);
}
}]);
return Cursor;
}(BasicCursor);
exports.Cursor = Cursor;
exports.default = Cursor;
},{"./AsyncEventEmitter":1,"./DocumentMatcher":9,"./DocumentProjector":11,"./DocumentRetriver":12,"./DocumentSorter":13,"./EJSON":14,"./cursor-processors/aggregate":21,"./cursor-processors/filter":22,"./cursor-processors/ifNotEmpty":23,"./cursor-processors/join":24,"./cursor-processors/joinAll":25,"./cursor-processors/joinEach":26,"./cursor-processors/joinObj":27,"./cursor-processors/map":28,"./cursor-processors/reduce":29,"./cursor-processors/sortFunc":30,"fast.js/forEach":43,"fast.js/map":50,"fast.js/object/assign":51,"fast.js/object/keys":53,"invariant":57}],7:[function(require,module,exports){
'use strict';
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CursorObservable = undefined;
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
};
}();
var _get = function get(object, property, receiver) {
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 {
return get(parent, property, receiver);
}
} else if ("value" in desc) {
return desc.value;
} else {
var getter = desc.get;if (getter === undefined) {
return undefined;
}return getter.call(receiver);
}
};
var _bind2 = require('fast.js/function/bind');
var _bind3 = _interopRequireDefault(_bind2);
var _checkTypes = require('check-types');
var _checkTypes2 = _interopRequireDefault(_checkTypes);
var _values2 = require('fast.js/object/values');
var _values3 = _interopRequireDefault(_values2);
var _map2 = require('fast.js/map');
var _map3 = _interopRequireDefault(_map2);
var _Cursor2 = require('./Cursor');
var _Cursor3 = _interopRequireDefault(_Cursor2);
var _EJSON = require('./EJSON');
var _EJSON2 = _interopRequireDefault(_EJSON);
var _PromiseQueue = require('./PromiseQueue');
var _PromiseQueue2 = _interopRequireDefault(_PromiseQueue);
var _debounce = require('./debounce');
var _debounce2 = _interopRequireDefault(_debounce);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor