UNPKG

mobdb

Version:

MarsDB is a lightweight client-side MongoDB-like database, Promise based, written in ES6

1,529 lines (1,263 loc) 582 kB
(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