diff --git a/.gitignore b/.gitignore index 614d027..5e54e47 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ node_modules/ .idea/ .DS_Store + +.nyc_output/ +coverage/ diff --git a/README.md b/README.md index 32f9a11..9f40af8 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,6 @@ It allows you to listen for storage events on any branch or leaf within the stor var handle = store.after('set', 'cars.stats.ordered', function(result) { // cars.stats.ordered was just set... what are you going to do about it? - // you can change the result that the calling code gets here - return result * 2; }; store.set('cars.stats.ordered', 30); @@ -48,13 +46,9 @@ It allows you to listen for storage events on any branch or leaf within the stor store.get('cars.stats.ordered'); // the answer is 30 again. that's better. - // you can also intercept storage events before they occur // (oh yeah, and you can use wildcards) - handle = store.before('set', 'cars.stats.ordered.*', function(k, v) { + handle = store.after('set', 'cars.stats.ordered.*', function(k, v) { // will execute any time any property is set onto cars.ordered - // and you can alter the storing key and value here by returning - // a new arguments array - return [k + '-foo', v * 20]; }); store.set('cars.stats.blue', 345); @@ -81,11 +75,23 @@ Each JSDS data store object created will have the following instance properties: * `id`: The id of the store * `set(key, value)`: Stores the given value for the given key * `get(key)`: Retrieves the value for given key, or undefined if it doesn't exist -* `before(event, [optional] key, callback, scope)`: Will call the function registered with original arguments before any action has been taken. You can alter the arguments by returning an array of new arguments. Returns an `handler` object with a `remove()` function, which will remove the listener. -* `after(event, [optional] key, callback, scope)`: Will call the function registered with the result of the action, after action has been taken. You can alter the result with a new return value. Returns an `handler` object with a `remove()` function, which will remove the listener. +* `after(event, [optional] key, callback, scope)`: Will call the function registered with the result of the action, after action has been taken. Returns an `handler` object with a `remove()` function, which will remove the listener. * `clear()`: Removes all stored data from the store * `remove()`: Removes all stored data from the store and deletes store reference within JSDS (for full deletion, any outside references must also be deleted) +Build +----- + + npm start + +This will build a webpack bundle in `docs/` + +Test +---- + + npm test + +Hopefully they all pass. AJAX Use Case ------------- diff --git a/docs/jsds-1.0.0.js b/docs/jsds-1.0.0.js index 13562ca..dcdfe69 100644 --- a/docs/jsds-1.0.0.js +++ b/docs/jsds-1.0.0.js @@ -71,6 +71,17 @@ /************************************************************************/ /******/ ({ +/***/ "./src/index.js": +/*!**********************!*\ + !*** ./src/index.js ***! + \**********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("window.JSDS = __webpack_require__(/*! ./jsds */ \"./src/jsds.js\");\n\n//# sourceURL=webpack:///./src/index.js?"); + +/***/ }), + /***/ "./src/jsds.js": /*!*********************!*\ !*** ./src/jsds.js ***! @@ -78,18 +89,18 @@ /*! no static exports found */ /***/ (function(module, exports) { -eval("/*\n * Copyright (c) 2010 Matthew A. Taylor\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n(function () {\n var REGEX_DOT_G = /\\./g,\n BSLASH_DOT = '\\.',\n REGEX_STAR_G = /\\*/g,\n ID_LENGTH = 16,\n\n // static export\n JSDS,\n\n // private props\n randoms = [],\n\n // private functions\n storeIt,\n update,\n mergeArraysIntoSet,\n arrayContains,\n arrayRemoveItem,\n fire,\n listenerApplies,\n removeListener,\n getCompleteKey,\n pullOutKeys,\n toRegex,\n valueMatchesKeyString,\n clone,\n getValue,\n getRandomId,\n generateRandomId;\n\n /*************************/\n /* The JSDataStore Class */\n /*************************/\n\n function JSDataStore(id) {\n // data stores\n this._s = {};\n // event listeners\n this._l = {};\n this.id = id;\n }\n\n JSDataStore.prototype = {\n\n /**\n * Stores data\n *\n * key {String}: the key to be used to store the data. The same key can be used to retrieve\n * the data\n * val {Object}: Any value to be stored in the store\n * opts {Object} (optional): options to be used when storing data:\n * 'update': if true, values already existing within objects and\n * arrays will not be clobbered\n * returns {Object}: The last value stored within specified key or undefined\n *\n * (fires 'store' event)\n */\n set: function (key, val, opts /*optional*/) {\n var result;\n opts = opts || { update: false };\n fire.call(this, 'set', {\n key: key,\n value: val,\n id: this.id,\n when: 'before',\n args: Array.prototype.slice.call(arguments, 0, arguments.length)\n });\n result = storeIt(this._s, key, opts, val);\n fire.call(this, 'set', {\n key: key,\n value: val,\n id: this.id,\n when: 'after',\n result: this.get(key, { quiet: true })\n });\n return result;\n },\n\n /**\n * Gets data back out of store\n *\n * key {String}: the key of the data you want back\n * returns {Object}: the data or undefined if key doesn't exist\n *\n * (fires 'get' event)\n */\n get: function (key) {\n var s = this._s,\n keys,\n i = 0,\n j = 0,\n opts,\n result,\n splitKeys,\n args = Array.prototype.slice.call(arguments, 0, arguments.length);\n\n opts = args[args.length - 1];\n if (typeof opts === 'string') {\n opts = {};\n } else {\n args.pop();\n }\n\n if (!opts.quiet) {\n fire.call(this, 'get', {\n key: key,\n when: 'before',\n args: args\n });\n }\n\n if (args.length === 1 && key.indexOf(BSLASH_DOT) < 0) {\n result = s[key];\n } else {\n if (args.length > 1) {\n keys = [];\n for (i = 0; i < args.length; i++) {\n if (args[i].indexOf(BSLASH_DOT) > -1) {\n splitKeys = args[i].split(BSLASH_DOT);\n for (j = 0; j < splitKeys.length; j++) {\n keys.push(splitKeys[j]);\n }\n } else {\n keys.push(args[i]);\n }\n }\n } else if (key.indexOf(BSLASH_DOT) > -1) {\n keys = key.split(BSLASH_DOT);\n }\n\n result = getValue(s, keys);\n }\n\n if (!opts.quiet) {\n fire.call(this, 'get', {\n key: key,\n value: result,\n when: 'after',\n result: result\n });\n }\n return result;\n },\n\n /**\n * Adds a listener to this store. The listener will be executed when an event of\n * the specified type is emitted and all the conditions defined in the parameters\n * are met.\n *\n * type {String}: the type of event to listen for ('store', 'get', 'clear', etc.)\n * options {object}: an object that contains one or more of the following configurations:\n * 'callback': the function to be executed\n * 'scope': the scope object for the callback execution\n * 'key': the storage key to listen for. If specified only stores into this key will\n * cause callback to be executed\n * 'when': 'before' or 'after' (default is 'after')\n */\n on: function (type, opts) {\n var me = this,\n cbid = getRandomId(),\n key = opts.key,\n fn = opts.callback,\n scope = opts.scope || this,\n when = opts.when || 'after';\n if (!this._l[type]) {\n this._l[type] = [];\n }\n this._l[type].push({ id: cbid, callback: fn, scope: scope, key: key, when: when });\n return {\n id: cbid,\n remove: function () {\n removeListener(me._l[type], cbid);\n }\n };\n },\n\n before: function (type, key, cb, scpe) {\n var callback = cb,\n scope = scpe;\n // key is optional\n if (typeof key === 'function') {\n callback = key;\n scope = cb;\n key = undefined;\n }\n return this.on(type, {\n callback: callback,\n key: key,\n when: 'before',\n scope: scope\n });\n },\n\n after: function (type, key, cb, scpe) {\n var callback = cb,\n scope = scpe;\n // key is optional\n if (typeof key === 'function') {\n callback = key;\n scope = cb;\n key = undefined;\n }\n return this.on(type, {\n callback: callback,\n key: key,\n when: 'after',\n scope: scope\n });\n },\n\n /**\n * Removes all data from store\n *\n * (fires 'clear' event)\n */\n clear: function () {\n this._s = {};\n fire.call(this, 'clear');\n },\n\n /**\n * Removes all internal references to this data store. Note that to entirely release\n * store object for garbage collection, you must also set any local references to the\n * store to null!\n *\n * (fires 'remove' and 'clear' events)\n */\n remove: function () {\n var ltype, optsArray, opts, i;\n this.clear();\n delete JSDS._stores[this.id];\n arrayRemoveItem(randoms, this.id);\n fire.call(this, 'remove');\n }\n };\n\n /*************************/\n /* Global JSDS namespace */\n /*************************/\n\n JSDS = {\n\n _stores: {},\n\n /**\n * Create a new data store object. If no id is specified, a random id will be\n * generated.\n *\n * id {String} (optional): to identify this store for events and later retrieval\n */\n create: function (id) {\n\n id = id || getRandomId();\n\n if (this._stores[id]) {\n throw new Error('Cannot overwrite existing data store \"' + id + '\"!');\n }\n\n this._stores[id] = new JSDataStore(id);\n\n return this._stores[id];\n },\n\n /**\n * Retrieves an existing data store object by id\n *\n * id {String}: the id of the store to retrieve\n * returns {JSDataStore} the data store\n */\n get: function (id) {\n return this._stores[id];\n },\n\n /**\n * Removes all data stores objects. Specifically, each JSDataStore object's remove()\n * method is called, and all local references to each are deleted.\n */\n clear: function () {\n var storeId;\n for (storeId in this._stores) {\n if (this._stores.hasOwnProperty(storeId)) {\n this._stores[storeId].remove();\n delete this._stores[storeId];\n }\n }\n this._stores = {};\n },\n\n /**\n * Returns a count of the existing data stores in memory\n */\n count: function () {\n var cnt = 0,\n p;\n for (p in this._stores) {\n if (this._stores.hasOwnProperty(p)) {\n cnt++;\n }\n }\n return cnt;\n },\n\n /**\n * Returns a list of ids [String] for all data store obects in memory\n */\n ids: function () {\n var id,\n ids = [];\n for (id in this._stores) {\n if (this._stores.hasOwnProperty(id)) {\n ids.push(id);\n }\n }\n return ids;\n }\n };\n\n /*****************/\n /* PRIVATE STUFF */\n /*****************/\n\n // recursive store function\n storeIt = function (store, key, opts, val, oldVal /*optional*/) {\n var result, keys, oldKey;\n if (key.indexOf(BSLASH_DOT) >= 0) {\n keys = key.split('.');\n oldVal = store[keys[0]] ? clone(store[keys[0]]) : undefined;\n oldKey = keys.shift();\n if (store[oldKey] === undefined) {\n store[oldKey] = {};\n }\n return storeIt(store[oldKey], keys.join('.'), opts, val, oldVal);\n }\n result = oldVal ? oldVal[key] : store[key];\n // if this is an update, and there is an old value to update\n if (opts.update) {\n update(store, val, key);\n }\n // if not an update, just overwrite the old value\n else {\n store[key] = val;\n }\n return result;\n };\n\n // recursive update function used to overwrite values within the store without\n // clobbering properties of objects\n update = function (store, val, key) {\n var vprop;\n if (typeof val !== 'object' || val instanceof Array) {\n if (store[key] && val instanceof Array) {\n mergeArraysIntoSet(store[key], val);\n } else {\n store[key] = val;\n }\n } else {\n for (vprop in val) {\n if (val.hasOwnProperty(vprop)) {\n if (!store[key]) {\n store[key] = {};\n }\n if (store[key].hasOwnProperty(vprop)) {\n update(store[key], val[vprop], vprop);\n } else {\n store[key][vprop] = val[vprop];\n }\n }\n }\n }\n };\n\n // merge two arrays without duplicate values\n mergeArraysIntoSet = function (lhs, rhs) {\n var i = 0;\n for (; i < rhs.length; i++) {\n if (!arrayContains(lhs, rhs[i])) {\n lhs.push(rhs[i]);\n }\n }\n };\n\n // internal utility function\n arrayContains = function (arr, val, comparator /* optional */) {\n var i = 0;\n comparator = comparator || function (lhs, rhs) {\n return lhs === rhs;\n };\n for (; i < arr.length; i++) {\n if (comparator(arr[i], val)) {\n return true;\n }\n }\n return false;\n };\n\n arrayRemoveItem = function (arr, item) {\n var i, needle;\n for (i = 0; i < arr.length; i++) {\n if (arr[i] === item) {\n needle = i;\n break;\n }\n }\n if (needle) {\n arr.splice(needle, 1);\n }\n };\n\n // fire an event of 'type' with included arguments to be passed to listeners functions\n // WARNING: this function must be invoked as fire.call(scope, type, args) because it uses 'this'.\n // The reason is so this function is not publicly exposed on JSDS instances\n fire = function (type, fireOptions) {\n var i,\n opts,\n scope,\n listeners,\n pulledKeys,\n listeners = this._l[type] || [];\n\n fireOptions = fireOptions || {};\n\n if (listeners.length) {\n for (i = 0; i < listeners.length; i++) {\n opts = listeners[i];\n if (listenerApplies.call(this, opts, fireOptions)) {\n scope = opts.scope || this;\n if (opts.key && fireOptions) {\n if (opts.key.indexOf('*') >= 0) {\n pulledKeys = pullOutKeys(fireOptions.value);\n fireOptions.value = {};\n fireOptions.value.key = fireOptions.key + pulledKeys;\n fireOptions.value.value = getValue(this._s, fireOptions.value.key.split('.'));\n } else {\n fireOptions.value = getValue(this._s, opts.key.split('.'));\n }\n }\n if (fireOptions.args) {\n opts.callback.apply(scope, fireOptions.args);\n } else if (fireOptions.result) {\n opts.callback.call(scope, fireOptions.result);\n } else {\n opts.callback.call(scope, type, fireOptions);\n }\n }\n }\n }\n };\n\n // WARNING: this function must be invoked as listenerApplies.call(scope, listener, crit) because it uses 'this'.\n // The reason is so this function is not publicly exposed on JSDS instances\n listenerApplies = function (listener, crit) {\n console.log(\"Event %s:%s ... does %s:%s apply?\", crit.when, crit.key, listener.when, listener.key);\n var result = false,\n last,\n sub,\n k,\n replacedKey,\n breakout = false;\n if (listener.when && crit.when) {\n if (listener.when !== crit.when) {\n return false;\n }\n }\n if (!listener.key || !crit) {\n return true;\n }\n if (!crit.key || crit.key.match(toRegex(listener.key))) {\n return true;\n }\n last = crit.key.length;\n while (!breakout) {\n sub = crit.key.substr(0, last);\n last = sub.lastIndexOf(BSLASH_DOT);\n if (last < 0) {\n k = sub;\n breakout = true;\n } else {\n k = sub.substr(0, last);\n }\n if (listener.key.indexOf('*') === 0) {\n return valueMatchesKeyString(crit.value, listener.key.replace(/\\*/, crit.key).substr(crit.key.length + 1));\n } else if (listener.key.indexOf('*') > 0) {\n replacedKey = getCompleteKey(crit);\n return toRegex(replacedKey).match(listener.key);\n }\n return valueMatchesKeyString(crit.value, listener.key.substr(crit.key.length + 1));\n }\n return result;\n };\n\n removeListener = function (listeners, id) {\n var i, l, needle;\n for (i = 0; i < listeners.length; i++) {\n l = listeners[i];\n if (l.id && l.id === id) {\n needle = i;\n break;\n }\n }\n if (typeof needle !== 'undefined') {\n listeners.splice(needle, 1);\n }\n };\n\n getCompleteKey = function (o) {\n var val = o.value,\n key = o.key;\n return key + pullOutKeys(val);\n };\n\n pullOutKeys = function (v) {\n var p,\n res = '';\n for (p in v) {\n if (v.hasOwnProperty(p)) {\n res += '.' + p;\n if (typeof v[p] === 'object' && !(v[p] instanceof Array)) {\n res += pullOutKeys(v[p]);\n }\n }\n }\n return res;\n };\n\n toRegex = function (s) {\n return s.replace(REGEX_DOT_G, '\\\\.').replace(REGEX_STAR_G, '\\.*');\n };\n\n valueMatchesKeyString = function (val, key) {\n var p,\n i = 0,\n keys = key.split('.');\n for (p in val) {\n if (val.hasOwnProperty(p)) {\n if (keys[i] === '*' || p === keys[i]) {\n if (typeof val[p] === 'object' && !(val[p] instanceof Array)) {\n return valueMatchesKeyString(val[p], keys.slice(i + 1).join('.'));\n } else {\n return true;\n }\n }\n }\n i++;\n }\n return false;\n };\n\n // used to copy branches within the store. Object and array friendly\n clone = function (val) {\n var newObj, i, prop;\n if (val instanceof Array) {\n newObj = [];\n for (i = 0; i < val.length; i++) {\n newObj[i] = clone(val[i]);\n }\n } else if (typeof val === 'object') {\n newObj = {};\n for (prop in val) {\n if (val.hasOwnProperty(prop)) {\n newObj[prop] = clone(val[prop]);\n }\n }\n } else {\n return val;\n }\n return newObj;\n };\n\n // returns a value from a store given an array of keys that is meant to describe depth\n // within the storage tree\n getValue = function (store, keys) {\n var key = keys.shift(),\n endKey,\n arrResult,\n p,\n keysClone;\n if (key === '*') {\n arrResult = [];\n for (p in store) {\n if (store.hasOwnProperty(p)) {\n keysClone = clone(keys);\n arrResult.push(getValue(store[p], keysClone));\n }\n }\n return arrResult;\n }\n if (keys[0] && store[key] && (store[key][keys[0]] || keys[0] === '*')) {\n return getValue(store[key], keys);\n } else {\n if (keys.length) {\n endKey = keys[0];\n } else {\n endKey = key;\n }\n return store[endKey];\n }\n };\n\n generateRandomId = function (length) {\n var text = \"\",\n i,\n possible = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n for (i = 0; i < length; i++) {\n text += possible.charAt(Math.floor(Math.random() * possible.length));\n }\n return text;\n };\n\n getRandomId = function () {\n var id = generateRandomId(ID_LENGTH);\n // no duplicate ids allowed\n while (arrayContains(randoms, id)) {\n id = generateRandomId(ID_LENGTH);\n }\n randoms.push(id);\n return id;\n };\n\n // for client side, attach to window\n if (typeof window !== 'undefined') {\n window.JSDS = JSDS;\n }\n // or export via CommonJS\n else {\n exports.JSDS = JSDS;\n }\n})();\n\n//# sourceURL=webpack:///./src/jsds.js?"); +eval("/*\n * Copyright (c) 2010 Matthew A. Taylor\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nvar REGEX_DOT_G = /\\./g,\n BSLASH_DOT = '\\.',\n REGEX_STAR_G = /\\*/g,\n ID_LENGTH = 16,\n\n// static export\nJSDS,\n\n// private props\nrandoms = [],\n\n// private functions\nstoreIt,\n update,\n mergeArraysIntoSet,\n arrayContains,\n arrayRemoveItem,\n fire,\n listenerApplies,\n removeListener,\n getCompleteKey,\n pullOutKeys,\n toRegex,\n valueMatchesKeyString,\n clone,\n getValue,\n getRandomId,\n generateRandomId;\n\n/*************************/\n/* The JSDataStore Class */\n/*************************/\n\nfunction JSDataStore(id) {\n // data stores\n this._s = {};\n // event listeners\n this._l = {};\n this.id = id;\n}\n\nJSDataStore.prototype = {\n\n /**\n * Stores data\n *\n * key {String}: the key to be used to store the data. The same key can be used to retrieve\n * the data\n * val {Object}: Any value to be stored in the store\n * opts {Object} (optional): options to be used when storing data:\n * 'update': if true, values already existing within objects and\n * arrays will not be clobbered\n * returns {Object}: The last value stored within specified key or undefined\n *\n * (fires 'store' event)\n */\n set: function (key, val, opts /*optional*/) {\n var result;\n opts = opts || { update: false };\n fire.call(this, 'set', {\n key: key,\n value: val,\n id: this.id,\n when: 'before',\n args: Array.prototype.slice.call(arguments, 0, arguments.length)\n });\n result = storeIt(this._s, key, opts, val);\n fire.call(this, 'set', {\n key: key,\n value: val,\n id: this.id,\n when: 'after',\n result: this.get(key, { quiet: true })\n });\n return result;\n },\n\n /**\n * Gets data back out of store\n *\n * key {String}: the key of the data you want back\n * returns {Object}: the data or undefined if key doesn't exist\n *\n * (fires 'get' event)\n */\n get: function (key) {\n var s = this._s,\n keys,\n i = 0,\n j = 0,\n opts,\n result,\n splitKeys,\n args = Array.prototype.slice.call(arguments, 0, arguments.length);\n\n opts = args[args.length - 1];\n if (typeof opts === 'string') {\n opts = {};\n } else {\n args.pop();\n }\n\n if (!opts.quiet) {\n fire.call(this, 'get', {\n key: key,\n when: 'before',\n args: args\n });\n }\n\n if (args.length === 1 && key.indexOf(BSLASH_DOT) < 0) {\n result = s[key];\n } else {\n if (args.length > 1) {\n keys = [];\n for (i = 0; i < args.length; i++) {\n if (args[i].indexOf(BSLASH_DOT) > -1) {\n splitKeys = args[i].split(BSLASH_DOT);\n for (j = 0; j < splitKeys.length; j++) {\n keys.push(splitKeys[j]);\n }\n } else {\n keys.push(args[i]);\n }\n }\n } else if (key.indexOf(BSLASH_DOT) > -1) {\n keys = key.split(BSLASH_DOT);\n }\n\n result = getValue(s, keys);\n }\n\n if (!opts.quiet) {\n fire.call(this, 'get', {\n key: key,\n value: result,\n when: 'after',\n result: result\n });\n }\n return result;\n },\n\n /**\n * Adds a listener to this store. The listener will be executed when an event of\n * the specified type is emitted and all the conditions defined in the parameters\n * are met.\n *\n * type {String}: the type of event to listen for ('store', 'get', 'clear', etc.)\n * options {object}: an object that contains one or more of the following configurations:\n * 'callback': the function to be executed\n * 'scope': the scope object for the callback execution\n * 'key': the storage key to listen for. If specified only stores into this key will\n * cause callback to be executed\n * 'when': 'before' or 'after' (default is 'after')\n */\n on: function (type, opts) {\n var me = this,\n cbid = getRandomId(),\n key = opts.key,\n fn = opts.callback,\n scope = opts.scope || this,\n when = opts.when || 'after';\n if (!this._l[type]) {\n this._l[type] = [];\n }\n this._l[type].push({ id: cbid, callback: fn, scope: scope, key: key, when: when });\n return {\n id: cbid,\n remove: function () {\n removeListener(me._l[type], cbid);\n }\n };\n },\n\n before: function (type, key, cb, scpe) {\n var callback = cb,\n scope = scpe;\n // key is optional\n if (typeof key === 'function') {\n callback = key;\n scope = cb;\n key = undefined;\n }\n return this.on(type, {\n callback: callback,\n key: key,\n when: 'before',\n scope: scope\n });\n },\n\n after: function (type, key, cb, scpe) {\n var callback = cb,\n scope = scpe;\n // key is optional\n if (typeof key === 'function') {\n callback = key;\n scope = cb;\n key = undefined;\n }\n return this.on(type, {\n callback: callback,\n key: key,\n when: 'after',\n scope: scope\n });\n },\n\n /**\n * Removes all data from store\n *\n * (fires 'clear' event)\n */\n clear: function () {\n this._s = {};\n fire.call(this, 'clear');\n },\n\n /**\n * Removes all internal references to this data store. Note that to entirely release\n * store object for garbage collection, you must also set any local references to the\n * store to null!\n *\n * (fires 'remove' and 'clear' events)\n */\n remove: function () {\n var ltype, optsArray, opts, i;\n this.clear();\n delete JSDS._stores[this.id];\n arrayRemoveItem(randoms, this.id);\n fire.call(this, 'remove');\n }\n};\n\n/*************************/\n/* Global JSDS namespace */\n/*************************/\n\nJSDS = {\n\n _stores: {},\n\n /**\n * Create a new data store object. If no id is specified, a random id will be\n * generated.\n *\n * id {String} (optional): to identify this store for events and later retrieval\n */\n create: function (id) {\n\n id = id || getRandomId();\n\n if (this._stores[id]) {\n throw new Error('Cannot overwrite existing data store \"' + id + '\"!');\n }\n\n this._stores[id] = new JSDataStore(id);\n\n return this._stores[id];\n },\n\n /**\n * Retrieves an existing data store object by id\n *\n * id {String}: the id of the store to retrieve\n * returns {JSDataStore} the data store\n */\n get: function (id) {\n return this._stores[id];\n },\n\n /**\n * Removes all data stores objects. Specifically, each JSDataStore object's remove()\n * method is called, and all local references to each are deleted.\n */\n clear: function () {\n var storeId;\n for (storeId in this._stores) {\n if (this._stores.hasOwnProperty(storeId)) {\n this._stores[storeId].remove();\n delete this._stores[storeId];\n }\n }\n this._stores = {};\n },\n\n /**\n * Returns a count of the existing data stores in memory\n */\n count: function () {\n var cnt = 0,\n p;\n for (p in this._stores) {\n if (this._stores.hasOwnProperty(p)) {\n cnt++;\n }\n }\n return cnt;\n },\n\n /**\n * Returns a list of ids [String] for all data store obects in memory\n */\n ids: function () {\n var id,\n ids = [];\n for (id in this._stores) {\n if (this._stores.hasOwnProperty(id)) {\n ids.push(id);\n }\n }\n return ids;\n }\n};\n\n/*****************/\n/* PRIVATE STUFF */\n/*****************/\n\n// recursive store function\nstoreIt = function (store, key, opts, val, oldVal /*optional*/) {\n var result, keys, oldKey;\n if (key.indexOf(BSLASH_DOT) >= 0) {\n keys = key.split('.');\n oldVal = store[keys[0]] ? clone(store[keys[0]]) : undefined;\n oldKey = keys.shift();\n if (store[oldKey] === undefined) {\n store[oldKey] = {};\n }\n return storeIt(store[oldKey], keys.join('.'), opts, val, oldVal);\n }\n result = oldVal ? oldVal[key] : store[key];\n // if this is an update, and there is an old value to update\n if (opts.update) {\n update(store, val, key);\n }\n // if not an update, just overwrite the old value\n else {\n store[key] = val;\n }\n return result;\n};\n\n// recursive update function used to overwrite values within the store without\n// clobbering properties of objects\nupdate = function (store, val, key) {\n var vprop;\n if (typeof val !== 'object' || val instanceof Array) {\n if (store[key] && val instanceof Array) {\n mergeArraysIntoSet(store[key], val);\n } else {\n store[key] = val;\n }\n } else {\n for (vprop in val) {\n if (val.hasOwnProperty(vprop)) {\n if (!store[key]) {\n store[key] = {};\n }\n if (store[key].hasOwnProperty(vprop)) {\n update(store[key], val[vprop], vprop);\n } else {\n store[key][vprop] = val[vprop];\n }\n }\n }\n }\n};\n\n// merge two arrays without duplicate values\nmergeArraysIntoSet = function (lhs, rhs) {\n var i = 0;\n for (; i < rhs.length; i++) {\n if (!arrayContains(lhs, rhs[i])) {\n lhs.push(rhs[i]);\n }\n }\n};\n\n// internal utility function\narrayContains = function (arr, val, comparator /* optional */) {\n var i = 0;\n comparator = comparator || function (lhs, rhs) {\n return lhs === rhs;\n };\n for (; i < arr.length; i++) {\n if (comparator(arr[i], val)) {\n return true;\n }\n }\n return false;\n};\n\narrayRemoveItem = function (arr, item) {\n var i, needle;\n for (i = 0; i < arr.length; i++) {\n if (arr[i] === item) {\n needle = i;\n break;\n }\n }\n if (needle) {\n arr.splice(needle, 1);\n }\n};\n\n// fire an event of 'type' with included arguments to be passed to listeners functions\n// WARNING: this function must be invoked as fire.call(scope, type, args) because it uses 'this'.\n// The reason is so this function is not publicly exposed on JSDS instances\nfire = function (type, fireOptions) {\n var i,\n opts,\n scope,\n listeners,\n pulledKeys,\n listeners = this._l[type] || [];\n\n fireOptions = fireOptions || {};\n\n if (listeners.length) {\n for (i = 0; i < listeners.length; i++) {\n opts = listeners[i];\n if (listenerApplies.call(this, opts, fireOptions)) {\n scope = opts.scope || this;\n if (opts.key && fireOptions) {\n if (opts.key.indexOf('*') >= 0) {\n pulledKeys = pullOutKeys(fireOptions.value);\n fireOptions.value = {};\n fireOptions.value.key = fireOptions.key + pulledKeys;\n fireOptions.value.value = getValue(this._s, fireOptions.value.key.split('.'));\n } else {\n fireOptions.value = getValue(this._s, opts.key.split('.'));\n }\n }\n if (fireOptions.args) {\n opts.callback.apply(scope, fireOptions.args);\n } else if (fireOptions.result) {\n opts.callback.call(scope, fireOptions.result);\n } else {\n opts.callback.call(scope, type, fireOptions);\n }\n }\n }\n }\n};\n\n// WARNING: this function must be invoked as listenerApplies.call(scope, listener, crit) because it uses 'this'.\n// The reason is so this function is not publicly exposed on JSDS instances\nlistenerApplies = function (listener, crit) {\n console.log(\"Event %s:%s ... does %s:%s apply?\", crit.when, crit.key, listener.when, listener.key);\n var result = false,\n last,\n sub,\n k,\n replacedKey,\n breakout = false;\n if (listener.when && crit.when) {\n if (listener.when !== crit.when) {\n return false;\n }\n }\n if (!listener.key || !crit) {\n return true;\n }\n if (!crit.key || crit.key.match(toRegex(listener.key))) {\n return true;\n }\n last = crit.key.length;\n while (!breakout) {\n sub = crit.key.substr(0, last);\n last = sub.lastIndexOf(BSLASH_DOT);\n if (last < 0) {\n k = sub;\n breakout = true;\n } else {\n k = sub.substr(0, last);\n }\n if (listener.key.indexOf('*') === 0) {\n return valueMatchesKeyString(crit.value, listener.key.replace(/\\*/, crit.key).substr(crit.key.length + 1));\n } else if (listener.key.indexOf('*') > 0) {\n replacedKey = getCompleteKey(crit);\n return toRegex(replacedKey).match(listener.key);\n }\n return valueMatchesKeyString(crit.value, listener.key.substr(crit.key.length + 1));\n }\n return result;\n};\n\nremoveListener = function (listeners, id) {\n var i, l, needle;\n for (i = 0; i < listeners.length; i++) {\n l = listeners[i];\n if (l.id && l.id === id) {\n needle = i;\n break;\n }\n }\n if (typeof needle !== 'undefined') {\n listeners.splice(needle, 1);\n }\n};\n\ngetCompleteKey = function (o) {\n var val = o.value,\n key = o.key;\n return key + pullOutKeys(val);\n};\n\npullOutKeys = function (v) {\n var p,\n res = '';\n for (p in v) {\n if (v.hasOwnProperty(p)) {\n res += '.' + p;\n if (typeof v[p] === 'object' && !(v[p] instanceof Array)) {\n res += pullOutKeys(v[p]);\n }\n }\n }\n return res;\n};\n\ntoRegex = function (s) {\n return s.replace(REGEX_DOT_G, '\\\\.').replace(REGEX_STAR_G, '\\.*');\n};\n\nvalueMatchesKeyString = function (val, key) {\n var p,\n i = 0,\n keys = key.split('.');\n for (p in val) {\n if (val.hasOwnProperty(p)) {\n if (keys[i] === '*' || p === keys[i]) {\n if (typeof val[p] === 'object' && !(val[p] instanceof Array)) {\n return valueMatchesKeyString(val[p], keys.slice(i + 1).join('.'));\n } else {\n return true;\n }\n }\n }\n i++;\n }\n return false;\n};\n\n// used to copy branches within the store. Object and array friendly\nclone = function (val) {\n var newObj, i, prop;\n if (val instanceof Array) {\n newObj = [];\n for (i = 0; i < val.length; i++) {\n newObj[i] = clone(val[i]);\n }\n } else if (typeof val === 'object') {\n newObj = {};\n for (prop in val) {\n if (val.hasOwnProperty(prop)) {\n newObj[prop] = clone(val[prop]);\n }\n }\n } else {\n return val;\n }\n return newObj;\n};\n\n// returns a value from a store given an array of keys that is meant to describe depth\n// within the storage tree\ngetValue = function (store, keys) {\n var key = keys.shift(),\n endKey,\n arrResult,\n p,\n keysClone;\n if (key === '*') {\n arrResult = [];\n for (p in store) {\n if (store.hasOwnProperty(p)) {\n keysClone = clone(keys);\n arrResult.push(getValue(store[p], keysClone));\n }\n }\n return arrResult;\n }\n if (keys[0] && store[key] && (store[key][keys[0]] || keys[0] === '*')) {\n return getValue(store[key], keys);\n } else {\n if (keys.length) {\n endKey = keys[0];\n } else {\n endKey = key;\n }\n return store[endKey];\n }\n};\n\ngenerateRandomId = function (length) {\n var text = \"\",\n i,\n possible = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n for (i = 0; i < length; i++) {\n text += possible.charAt(Math.floor(Math.random() * possible.length));\n }\n return text;\n};\n\ngetRandomId = function () {\n var id = generateRandomId(ID_LENGTH);\n // no duplicate ids allowed\n while (arrayContains(randoms, id)) {\n id = generateRandomId(ID_LENGTH);\n }\n randoms.push(id);\n return id;\n};\n\nmodule.exports = JSDS;\n\n//# sourceURL=webpack:///./src/jsds.js?"); /***/ }), /***/ 0: -/*!***************************!*\ - !*** multi ./src/jsds.js ***! - \***************************/ +/*!****************************!*\ + !*** multi ./src/index.js ***! + \****************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -eval("module.exports = __webpack_require__(/*! ./src/jsds.js */\"./src/jsds.js\");\n\n\n//# sourceURL=webpack:///multi_./src/jsds.js?"); +eval("module.exports = __webpack_require__(/*! ./src/index.js */\"./src/index.js\");\n\n\n//# sourceURL=webpack:///multi_./src/index.js?"); /***/ }) diff --git a/docs/jsds-1.0.2.js b/docs/jsds-1.0.2.js new file mode 100644 index 0000000..ef955e0 --- /dev/null +++ b/docs/jsds-1.0.2.js @@ -0,0 +1,107 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./src/index.js": +/*!**********************!*\ + !*** ./src/index.js ***! + \**********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("window.JSDS = __webpack_require__(/*! ./jsds */ \"./src/jsds.js\");\n\n//# sourceURL=webpack:///./src/index.js?"); + +/***/ }), + +/***/ "./src/jsds.js": +/*!*********************!*\ + !*** ./src/jsds.js ***! + \*********************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("/*\n * Copyright (c) 2010 Matthew A. Taylor\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nvar REGEX_DOT_G = /\\./g,\n BSLASH_DOT = '\\.',\n REGEX_STAR_G = /\\*/g,\n ID_LENGTH = 16,\n\n// static export\nJSDS,\n\n// private props\nrandoms = [],\n\n// private functions\nstoreIt,\n update,\n mergeArraysIntoSet,\n arrayContains,\n arrayRemoveItem,\n fire,\n listenerApplies,\n removeListener,\n getCompleteKey,\n pullOutKeys,\n toRegex,\n valueMatchesKeyString,\n clone,\n getValue,\n getRandomId,\n generateRandomId;\n\n/*************************/\n/* The JSDataStore Class */\n/*************************/\n\nfunction JSDataStore(id) {\n // data stores\n this._s = {};\n // event listeners\n this._l = {};\n this.id = id;\n}\n\nJSDataStore.prototype = {\n\n /**\n * Stores data\n *\n * key {String}: the key to be used to store the data. The same key can be used to retrieve\n * the data\n * val {Object}: Any value to be stored in the store\n * opts {Object} (optional): options to be used when storing data:\n * 'update': if true, values already existing within objects and\n * arrays will not be clobbered\n * returns {Object}: The last value stored within specified key or undefined\n *\n * (fires 'store' event)\n */\n set: function (key, val, opts /*optional*/) {\n var result;\n opts = opts || { update: false };\n fire.call(this, 'set', {\n key: key,\n value: val,\n id: this.id,\n when: 'before',\n args: Array.prototype.slice.call(arguments, 0, arguments.length)\n });\n result = storeIt(this._s, key, opts, val);\n fire.call(this, 'set', {\n key: key,\n value: val,\n id: this.id,\n when: 'after',\n result: this.get(key, { quiet: true })\n });\n return result;\n },\n\n /**\n * Gets data back out of store\n *\n * key {String}: the key of the data you want back\n * returns {Object}: the data or undefined if key doesn't exist\n *\n * (fires 'get' event)\n */\n get: function (key) {\n var s = this._s,\n keys,\n i = 0,\n j = 0,\n opts,\n result,\n splitKeys,\n args = Array.prototype.slice.call(arguments, 0, arguments.length);\n\n opts = args[args.length - 1];\n if (typeof opts === 'string') {\n opts = {};\n } else {\n args.pop();\n }\n\n if (!opts.quiet) {\n fire.call(this, 'get', {\n key: key,\n when: 'before',\n args: args\n });\n }\n\n if (args.length === 1 && key.indexOf(BSLASH_DOT) < 0) {\n result = s[key];\n } else {\n if (args.length > 1) {\n keys = [];\n for (i = 0; i < args.length; i++) {\n if (args[i].indexOf(BSLASH_DOT) > -1) {\n splitKeys = args[i].split(BSLASH_DOT);\n for (j = 0; j < splitKeys.length; j++) {\n keys.push(splitKeys[j]);\n }\n } else {\n keys.push(args[i]);\n }\n }\n } else if (key.indexOf(BSLASH_DOT) > -1) {\n keys = key.split(BSLASH_DOT);\n }\n\n result = getValue(s, keys);\n }\n\n if (!opts.quiet) {\n fire.call(this, 'get', {\n key: key,\n value: result,\n when: 'after',\n result: result\n });\n }\n return result;\n },\n\n /**\n * Adds a listener to this store. The listener will be executed when an event of\n * the specified type is emitted and all the conditions defined in the parameters\n * are met.\n *\n * type {String}: the type of event to listen for ('store', 'get', 'clear', etc.)\n * options {object}: an object that contains one or more of the following configurations:\n * 'callback': the function to be executed\n * 'scope': the scope object for the callback execution\n * 'key': the storage key to listen for. If specified only stores into this key will\n * cause callback to be executed\n * 'when': 'before' or 'after' (default is 'after')\n */\n on: function (type, opts) {\n var me = this,\n cbid = getRandomId(),\n key = opts.key,\n fn = opts.callback,\n scope = opts.scope || this,\n when = opts.when || 'after';\n if (!this._l[type]) {\n this._l[type] = [];\n }\n this._l[type].push({ id: cbid, callback: fn, scope: scope, key: key, when: when });\n return {\n id: cbid,\n remove: function () {\n removeListener(me._l[type], cbid);\n }\n };\n },\n\n before: function (type, key, cb, scpe) {\n var callback = cb,\n scope = scpe;\n // key is optional\n if (typeof key === 'function') {\n callback = key;\n scope = cb;\n key = undefined;\n }\n return this.on(type, {\n callback: callback,\n key: key,\n when: 'before',\n scope: scope\n });\n },\n\n after: function (type, key, cb, scpe) {\n var callback = cb,\n scope = scpe;\n // key is optional\n if (typeof key === 'function') {\n callback = key;\n scope = cb;\n key = undefined;\n }\n return this.on(type, {\n callback: callback,\n key: key,\n when: 'after',\n scope: scope\n });\n },\n\n /**\n * Removes all data from store\n *\n * (fires 'clear' event)\n */\n clear: function () {\n this._s = {};\n fire.call(this, 'clear');\n },\n\n /**\n * Removes all internal references to this data store. Note that to entirely release\n * store object for garbage collection, you must also set any local references to the\n * store to null!\n *\n * (fires 'remove' and 'clear' events)\n */\n remove: function () {\n var ltype, optsArray, opts, i;\n this.clear();\n delete JSDS._stores[this.id];\n arrayRemoveItem(randoms, this.id);\n fire.call(this, 'remove');\n }\n};\n\n/*************************/\n/* Global JSDS namespace */\n/*************************/\n\nJSDS = {\n\n _stores: {},\n\n /**\n * Create a new data store object. If no id is specified, a random id will be\n * generated.\n *\n * id {String} (optional): to identify this store for events and later retrieval\n */\n create: function (id) {\n\n id = id || getRandomId();\n\n if (this._stores[id]) {\n throw new Error('Cannot overwrite existing data store \"' + id + '\"!');\n }\n\n this._stores[id] = new JSDataStore(id);\n\n return this._stores[id];\n },\n\n /**\n * Retrieves an existing data store object by id\n *\n * id {String}: the id of the store to retrieve\n * returns {JSDataStore} the data store\n */\n get: function (id) {\n return this._stores[id];\n },\n\n /**\n * Removes all data stores objects. Specifically, each JSDataStore object's remove()\n * method is called, and all local references to each are deleted.\n */\n clear: function () {\n var storeId;\n for (storeId in this._stores) {\n if (this._stores.hasOwnProperty(storeId)) {\n this._stores[storeId].remove();\n delete this._stores[storeId];\n }\n }\n this._stores = {};\n },\n\n /**\n * Returns a count of the existing data stores in memory\n */\n count: function () {\n var cnt = 0,\n p;\n for (p in this._stores) {\n if (this._stores.hasOwnProperty(p)) {\n cnt++;\n }\n }\n return cnt;\n },\n\n /**\n * Returns a list of ids [String] for all data store obects in memory\n */\n ids: function () {\n var id,\n ids = [];\n for (id in this._stores) {\n if (this._stores.hasOwnProperty(id)) {\n ids.push(id);\n }\n }\n return ids;\n }\n};\n\n/*****************/\n/* PRIVATE STUFF */\n/*****************/\n\n// recursive store function\nstoreIt = function (store, key, opts, val, oldVal /*optional*/) {\n var result, keys, oldKey;\n if (key.indexOf(BSLASH_DOT) >= 0) {\n keys = key.split('.');\n oldVal = store[keys[0]] ? clone(store[keys[0]]) : undefined;\n oldKey = keys.shift();\n if (store[oldKey] === undefined) {\n store[oldKey] = {};\n }\n return storeIt(store[oldKey], keys.join('.'), opts, val, oldVal);\n }\n result = oldVal ? oldVal[key] : store[key];\n // if this is an update, and there is an old value to update\n if (opts.update) {\n update(store, val, key);\n }\n // if not an update, just overwrite the old value\n else {\n store[key] = val;\n }\n return result;\n};\n\n// recursive update function used to overwrite values within the store without\n// clobbering properties of objects\nupdate = function (store, val, key) {\n var vprop;\n if (typeof val !== 'object' || val instanceof Array) {\n if (store[key] && val instanceof Array) {\n mergeArraysIntoSet(store[key], val);\n } else {\n store[key] = val;\n }\n } else {\n for (vprop in val) {\n if (val.hasOwnProperty(vprop)) {\n if (!store[key]) {\n store[key] = {};\n }\n if (store[key].hasOwnProperty(vprop)) {\n update(store[key], val[vprop], vprop);\n } else {\n store[key][vprop] = val[vprop];\n }\n }\n }\n }\n};\n\n// merge two arrays without duplicate values\nmergeArraysIntoSet = function (lhs, rhs) {\n var i = 0;\n for (; i < rhs.length; i++) {\n if (!arrayContains(lhs, rhs[i])) {\n lhs.push(rhs[i]);\n }\n }\n};\n\n// internal utility function\narrayContains = function (arr, val, comparator /* optional */) {\n var i = 0;\n comparator = comparator || function (lhs, rhs) {\n return lhs === rhs;\n };\n for (; i < arr.length; i++) {\n if (comparator(arr[i], val)) {\n return true;\n }\n }\n return false;\n};\n\narrayRemoveItem = function (arr, item) {\n var i, needle;\n for (i = 0; i < arr.length; i++) {\n if (arr[i] === item) {\n needle = i;\n break;\n }\n }\n if (needle) {\n arr.splice(needle, 1);\n }\n};\n\n// fire an event of 'type' with included arguments to be passed to listeners functions\n// WARNING: this function must be invoked as fire.call(scope, type, args) because it uses 'this'.\n// The reason is so this function is not publicly exposed on JSDS instances\nfire = function (type, fireOptions) {\n var i,\n opts,\n scope,\n listeners,\n pulledKeys,\n listeners = this._l[type] || [];\n\n fireOptions = fireOptions || {};\n\n if (listeners.length) {\n for (i = 0; i < listeners.length; i++) {\n opts = listeners[i];\n if (listenerApplies.call(this, opts, fireOptions)) {\n scope = opts.scope || this;\n if (opts.key && fireOptions) {\n if (opts.key.indexOf('*') >= 0) {\n pulledKeys = pullOutKeys(fireOptions.value);\n fireOptions.value = {};\n fireOptions.value.key = fireOptions.key + pulledKeys;\n fireOptions.value.value = getValue(this._s, fireOptions.value.key.split('.'));\n } else {\n fireOptions.value = getValue(this._s, opts.key.split('.'));\n }\n }\n if (fireOptions.args) {\n opts.callback.apply(scope, fireOptions.args);\n } else if (fireOptions.result) {\n opts.callback.call(scope, fireOptions.result);\n } else {\n opts.callback.call(scope, fireOptions.result);\n }\n }\n }\n }\n};\n\n// WARNING: this function must be invoked as listenerApplies.call(scope, listener, crit) because it uses 'this'.\n// The reason is so this function is not publicly exposed on JSDS instances\nlistenerApplies = function (listener, crit) {\n var result = false,\n last,\n sub,\n k,\n replacedKey,\n breakout = false;\n if (listener.when && crit.when) {\n if (listener.when !== crit.when) {\n return false;\n }\n }\n if (!listener.key || !crit) {\n return true;\n }\n if (!crit.key || crit.key.match(toRegex(listener.key))) {\n return true;\n }\n last = crit.key.length;\n while (!breakout) {\n sub = crit.key.substr(0, last);\n last = sub.lastIndexOf(BSLASH_DOT);\n if (last < 0) {\n k = sub;\n breakout = true;\n } else {\n k = sub.substr(0, last);\n }\n if (listener.key.indexOf('*') === 0) {\n return valueMatchesKeyString(crit.value, listener.key.replace(/\\*/, crit.key).substr(crit.key.length + 1));\n } else if (listener.key.indexOf('*') > 0) {\n replacedKey = getCompleteKey(crit);\n return toRegex(replacedKey).match(listener.key);\n }\n return valueMatchesKeyString(crit.value, listener.key.substr(crit.key.length + 1));\n }\n return result;\n};\n\nremoveListener = function (listeners, id) {\n var i, l, needle;\n for (i = 0; i < listeners.length; i++) {\n l = listeners[i];\n if (l.id && l.id === id) {\n needle = i;\n break;\n }\n }\n if (typeof needle !== 'undefined') {\n listeners.splice(needle, 1);\n }\n};\n\ngetCompleteKey = function (o) {\n var val = o.value,\n key = o.key;\n return key + pullOutKeys(val);\n};\n\npullOutKeys = function (v) {\n var p,\n res = '';\n for (p in v) {\n if (v.hasOwnProperty(p)) {\n res += '.' + p;\n if (typeof v[p] === 'object' && !(v[p] instanceof Array)) {\n res += pullOutKeys(v[p]);\n }\n }\n }\n return res;\n};\n\ntoRegex = function (s) {\n return s.replace(REGEX_DOT_G, '\\\\.').replace(REGEX_STAR_G, '\\.*');\n};\n\nvalueMatchesKeyString = function (val, key) {\n var p,\n i = 0,\n keys = key.split('.');\n for (p in val) {\n if (val.hasOwnProperty(p)) {\n if (keys[i] === '*' || p === keys[i]) {\n if (typeof val[p] === 'object' && !(val[p] instanceof Array)) {\n return valueMatchesKeyString(val[p], keys.slice(i + 1).join('.'));\n } else {\n return true;\n }\n }\n }\n i++;\n }\n return false;\n};\n\n// used to copy branches within the store. Object and array friendly\nclone = function (val) {\n var newObj, i, prop;\n if (val instanceof Array) {\n newObj = [];\n for (i = 0; i < val.length; i++) {\n newObj[i] = clone(val[i]);\n }\n } else if (typeof val === 'object') {\n newObj = {};\n for (prop in val) {\n if (val.hasOwnProperty(prop)) {\n newObj[prop] = clone(val[prop]);\n }\n }\n } else {\n return val;\n }\n return newObj;\n};\n\n// returns a value from a store given an array of keys that is meant to describe depth\n// within the storage tree\ngetValue = function (store, keys) {\n var key = keys.shift(),\n endKey,\n arrResult,\n p,\n keysClone;\n if (key === '*') {\n arrResult = [];\n for (p in store) {\n if (store.hasOwnProperty(p)) {\n keysClone = clone(keys);\n arrResult.push(getValue(store[p], keysClone));\n }\n }\n return arrResult;\n }\n if (keys[0] && store[key] && (store[key][keys[0]] || keys[0] === '*')) {\n return getValue(store[key], keys);\n } else {\n if (keys.length) {\n endKey = keys[0];\n } else {\n endKey = key;\n }\n return store[endKey];\n }\n};\n\ngenerateRandomId = function (length) {\n var text = \"\",\n i,\n possible = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n for (i = 0; i < length; i++) {\n text += possible.charAt(Math.floor(Math.random() * possible.length));\n }\n return text;\n};\n\ngetRandomId = function () {\n var id = generateRandomId(ID_LENGTH);\n // no duplicate ids allowed\n while (arrayContains(randoms, id)) {\n id = generateRandomId(ID_LENGTH);\n }\n randoms.push(id);\n return id;\n};\n\nmodule.exports = JSDS;\n\n//# sourceURL=webpack:///./src/jsds.js?"); + +/***/ }), + +/***/ 0: +/*!****************************!*\ + !*** multi ./src/index.js ***! + \****************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("module.exports = __webpack_require__(/*! ./src/index.js */\"./src/index.js\");\n\n\n//# sourceURL=webpack:///multi_./src/index.js?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/docs/jsds-1.0.3.js b/docs/jsds-1.0.3.js new file mode 100644 index 0000000..02a813d --- /dev/null +++ b/docs/jsds-1.0.3.js @@ -0,0 +1,107 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./src/index.js": +/*!**********************!*\ + !*** ./src/index.js ***! + \**********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("window.JSDS = __webpack_require__(/*! ./jsds */ \"./src/jsds.js\");\n\n//# sourceURL=webpack:///./src/index.js?"); + +/***/ }), + +/***/ "./src/jsds.js": +/*!*********************!*\ + !*** ./src/jsds.js ***! + \*********************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +eval("/*\n * Copyright (c) 2010 Matthew A. Taylor\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\nvar REGEX_DOT_G = /\\./g,\n BSLASH_DOT = '\\.',\n REGEX_STAR_G = /\\*/g,\n ID_LENGTH = 16,\n\n// static export\nJSDS,\n\n// private props\nrandoms = [],\n\n// private functions\nstoreIt,\n update,\n mergeArraysIntoSet,\n arrayContains,\n arrayRemoveItem,\n fire,\n listenerApplies,\n removeListener,\n getCompleteKey,\n pullOutKeys,\n toRegex,\n valueMatchesKeyString,\n clone,\n getValue,\n getRandomId,\n generateRandomId;\n\n/*************************/\n/* The JSDataStore Class */\n/*************************/\n\nfunction JSDataStore(id) {\n // data stores\n this._s = {};\n // event listeners\n this._l = {};\n this.id = id;\n}\n\nJSDataStore.prototype = {\n\n /**\n * Stores data\n *\n * key {String}: the key to be used to store the data. The same key can be used to retrieve\n * the data\n * val {Object}: Any value to be stored in the store\n * opts {Object} (optional): options to be used when storing data:\n * 'update': if true, values already existing within objects and\n * arrays will not be clobbered\n * returns {Object}: The last value stored within specified key or undefined\n *\n * (fires 'store' event)\n */\n set: function (key, val, opts /*optional*/) {\n var result;\n opts = opts || { update: false };\n fire.call(this, 'set', {\n key: key,\n value: val,\n id: this.id,\n when: 'before',\n args: Array.prototype.slice.call(arguments, 0, arguments.length)\n });\n result = storeIt(this._s, key, opts, val);\n fire.call(this, 'set', {\n key: key,\n value: val,\n id: this.id,\n when: 'after',\n result: this.get(key, { quiet: true })\n });\n return result;\n },\n\n /**\n * Gets data back out of store\n *\n * key {String}: the key of the data you want back\n * returns {Object}: the data or undefined if key doesn't exist\n *\n * (fires 'get' event)\n */\n get: function (key) {\n var s = this._s,\n keys,\n i = 0,\n j = 0,\n opts,\n result,\n splitKeys,\n args = Array.prototype.slice.call(arguments, 0, arguments.length);\n\n opts = args[args.length - 1];\n if (typeof opts === 'string') {\n opts = {};\n } else {\n args.pop();\n }\n\n if (!opts.quiet) {\n fire.call(this, 'get', {\n key: key,\n when: 'before',\n args: args\n });\n }\n\n if (args.length === 1 && key.indexOf(BSLASH_DOT) < 0) {\n result = s[key];\n } else {\n if (args.length > 1) {\n keys = [];\n for (i = 0; i < args.length; i++) {\n if (args[i].indexOf(BSLASH_DOT) > -1) {\n splitKeys = args[i].split(BSLASH_DOT);\n for (j = 0; j < splitKeys.length; j++) {\n keys.push(splitKeys[j]);\n }\n } else {\n keys.push(args[i]);\n }\n }\n } else if (key.indexOf(BSLASH_DOT) > -1) {\n keys = key.split(BSLASH_DOT);\n }\n\n result = getValue(s, keys);\n }\n\n if (!opts.quiet) {\n fire.call(this, 'get', {\n key: key,\n value: result,\n when: 'after',\n result: result\n });\n }\n return result;\n },\n\n /**\n * Adds a listener to this store. The listener will be executed when an event of\n * the specified type is emitted and all the conditions defined in the parameters\n * are met.\n *\n * type {String}: the type of event to listen for ('set', 'get', 'clear', etc.)\n * options {object}: an object that contains one or more of the following configurations:\n * 'callback': the function to be executed\n * 'scope': the scope object for the callback execution\n * 'key': the storage key to listen for. If specified only stores into this key will\n * cause callback to be executed\n * 'when': 'before' or 'after' (default is 'after')\n */\n on: function (type, opts) {\n var me = this,\n cbid = getRandomId(),\n key = opts.key,\n fn = opts.callback,\n scope = opts.scope || this,\n when = opts.when || 'after';\n if (!this._l[type]) {\n this._l[type] = [];\n }\n this._l[type].push({ id: cbid, callback: fn, scope: scope, key: key, when: when });\n return {\n id: cbid,\n remove: function () {\n removeListener(me._l[type], cbid);\n }\n };\n },\n\n before: function (type, key, cb, scpe) {\n var callback = cb,\n scope = scpe;\n // key is optional\n if (typeof key === 'function') {\n callback = key;\n scope = cb;\n key = undefined;\n }\n return this.on(type, {\n callback: callback,\n key: key,\n when: 'before',\n scope: scope\n });\n },\n\n after: function (type, key, cb, scpe) {\n var callback = cb,\n scope = scpe;\n // key is optional\n if (typeof key === 'function') {\n callback = key;\n scope = cb;\n key = undefined;\n }\n return this.on(type, {\n callback: callback,\n key: key,\n when: 'after',\n scope: scope\n });\n },\n\n /**\n * Removes all data from store\n *\n * (fires 'clear' event)\n */\n clear: function () {\n this._s = {};\n fire.call(this, 'clear');\n },\n\n /**\n * Removes all internal references to this data store. Note that to entirely release\n * store object for garbage collection, you must also set any local references to the\n * store to null!\n *\n * (fires 'remove' and 'clear' events)\n */\n remove: function () {\n var ltype, optsArray, opts, i;\n this.clear();\n delete JSDS._stores[this.id];\n arrayRemoveItem(randoms, this.id);\n fire.call(this, 'remove');\n }\n};\n\n/*************************/\n/* Global JSDS namespace */\n/*************************/\n\nJSDS = {\n\n _stores: {},\n\n /**\n * Create a new data store object. If no id is specified, a random id will be\n * generated.\n *\n * id {String} (optional): to identify this store for events and later retrieval\n */\n create: function (id) {\n\n id = id || getRandomId();\n\n if (this._stores[id]) {\n throw new Error('Cannot overwrite existing data store \"' + id + '\"!');\n }\n\n this._stores[id] = new JSDataStore(id);\n\n return this._stores[id];\n },\n\n /**\n * Retrieves an existing data store object by id\n *\n * id {String}: the id of the store to retrieve\n * returns {JSDataStore} the data store\n */\n get: function (id) {\n return this._stores[id];\n },\n\n /**\n * Removes all data stores objects. Specifically, each JSDataStore object's remove()\n * method is called, and all local references to each are deleted.\n */\n clear: function () {\n var storeId;\n for (storeId in this._stores) {\n if (this._stores.hasOwnProperty(storeId)) {\n this._stores[storeId].remove();\n delete this._stores[storeId];\n }\n }\n this._stores = {};\n },\n\n /**\n * Returns a count of the existing data stores in memory\n */\n count: function () {\n var cnt = 0,\n p;\n for (p in this._stores) {\n if (this._stores.hasOwnProperty(p)) {\n cnt++;\n }\n }\n return cnt;\n },\n\n /**\n * Returns a list of ids [String] for all data store obects in memory\n */\n ids: function () {\n var id,\n ids = [];\n for (id in this._stores) {\n if (this._stores.hasOwnProperty(id)) {\n ids.push(id);\n }\n }\n return ids;\n }\n};\n\n/*****************/\n/* PRIVATE STUFF */\n/*****************/\n\n// recursive store function\nstoreIt = function (store, key, opts, val, oldVal /*optional*/) {\n var result, keys, oldKey;\n if (key.indexOf(BSLASH_DOT) >= 0) {\n keys = key.split('.');\n oldVal = store[keys[0]] ? clone(store[keys[0]]) : undefined;\n oldKey = keys.shift();\n if (store[oldKey] === undefined) {\n store[oldKey] = {};\n }\n return storeIt(store[oldKey], keys.join('.'), opts, val, oldVal);\n }\n result = oldVal ? oldVal[key] : store[key];\n // if this is an update, and there is an old value to update\n if (opts.update) {\n update(store, val, key);\n }\n // if not an update, just overwrite the old value\n else {\n store[key] = val;\n }\n return result;\n};\n\n// recursive update function used to overwrite values within the store without\n// clobbering properties of objects\nupdate = function (store, val, key) {\n var vprop;\n if (typeof val !== 'object' || val instanceof Array) {\n if (store[key] && val instanceof Array) {\n mergeArraysIntoSet(store[key], val);\n } else {\n store[key] = val;\n }\n } else {\n for (vprop in val) {\n if (val.hasOwnProperty(vprop)) {\n if (!store[key]) {\n store[key] = {};\n }\n if (store[key].hasOwnProperty(vprop)) {\n update(store[key], val[vprop], vprop);\n } else {\n store[key][vprop] = val[vprop];\n }\n }\n }\n }\n};\n\n// merge two arrays without duplicate values\nmergeArraysIntoSet = function (lhs, rhs) {\n var i = 0;\n for (; i < rhs.length; i++) {\n if (!arrayContains(lhs, rhs[i])) {\n lhs.push(rhs[i]);\n }\n }\n};\n\n// internal utility function\narrayContains = function (arr, val, comparator /* optional */) {\n var i = 0;\n comparator = comparator || function (lhs, rhs) {\n return lhs === rhs;\n };\n for (; i < arr.length; i++) {\n if (comparator(arr[i], val)) {\n return true;\n }\n }\n return false;\n};\n\narrayRemoveItem = function (arr, item) {\n var i, needle;\n for (i = 0; i < arr.length; i++) {\n if (arr[i] === item) {\n needle = i;\n break;\n }\n }\n if (needle) {\n arr.splice(needle, 1);\n }\n};\n\n// fire an event of 'type' with included arguments to be passed to listeners functions\n// WARNING: this function must be invoked as fire.call(scope, type, args) because it uses 'this'.\n// The reason is so this function is not publicly exposed on JSDS instances\nfire = function (type, fireOptions) {\n var i,\n opts,\n scope,\n listeners,\n pulledKeys,\n listeners = this._l[type] || [];\n\n fireOptions = fireOptions || {};\n\n if (listeners.length) {\n for (i = 0; i < listeners.length; i++) {\n opts = listeners[i];\n if (listenerApplies.call(this, opts, fireOptions)) {\n scope = opts.scope || this;\n if (opts.key && fireOptions) {\n if (opts.key.indexOf('*') >= 0) {\n pulledKeys = pullOutKeys(fireOptions.value);\n fireOptions.value = {};\n fireOptions.value.key = fireOptions.key + pulledKeys;\n fireOptions.value.value = getValue(this._s, fireOptions.value.key.split('.'));\n } else {\n fireOptions.value = getValue(this._s, opts.key.split('.'));\n }\n }\n if (fireOptions.args) {\n opts.callback.apply(scope, fireOptions.args);\n } else if (fireOptions.result) {\n opts.callback.call(scope, fireOptions.result);\n } else {\n opts.callback.call(scope, fireOptions.result);\n }\n }\n }\n }\n};\n\n// WARNING: this function must be invoked as listenerApplies.call(scope, listener, crit) because it uses 'this'.\n// The reason is so this function is not publicly exposed on JSDS instances\nlistenerApplies = function (listener, crit) {\n var result = false,\n last,\n sub,\n k,\n replacedKey,\n breakout = false;\n if (listener.when && crit.when) {\n if (listener.when !== crit.when) {\n return false;\n }\n }\n if (!listener.key || !crit) {\n return true;\n }\n if (!crit.key || crit.key.match(toRegex('\\\\b' + listener.key + '\\\\b'))) {\n return true;\n }\n last = crit.key.length;\n while (!breakout) {\n sub = crit.key.substr(0, last);\n last = sub.lastIndexOf(BSLASH_DOT);\n if (last < 0) {\n k = sub;\n breakout = true;\n } else {\n k = sub.substr(0, last);\n }\n if (listener.key.indexOf('*') === 0) {\n return valueMatchesKeyString(crit.value, listener.key.replace(/\\*/, crit.key).substr(crit.key.length + 1));\n } else if (listener.key.indexOf('*') > 0) {\n replacedKey = getCompleteKey(crit);\n return toRegex(replacedKey).match(listener.key);\n }\n return valueMatchesKeyString(crit.value, listener.key.substr(crit.key.length + 1));\n }\n return result;\n};\n\nremoveListener = function (listeners, id) {\n var i, l, needle;\n for (i = 0; i < listeners.length; i++) {\n l = listeners[i];\n if (l.id && l.id === id) {\n needle = i;\n break;\n }\n }\n if (typeof needle !== 'undefined') {\n listeners.splice(needle, 1);\n }\n};\n\ngetCompleteKey = function (o) {\n var val = o.value,\n key = o.key;\n return key + pullOutKeys(val);\n};\n\npullOutKeys = function (v) {\n var p,\n res = '';\n for (p in v) {\n if (v.hasOwnProperty(p)) {\n res += '.' + p;\n if (typeof v[p] === 'object' && !(v[p] instanceof Array)) {\n res += pullOutKeys(v[p]);\n }\n }\n }\n return res;\n};\n\ntoRegex = function (s) {\n return s.replace(REGEX_DOT_G, '\\\\.').replace(REGEX_STAR_G, '\\.*');\n};\n\nvalueMatchesKeyString = function (val, key) {\n var p,\n i = 0,\n keys = key.split('.');\n for (p in val) {\n if (val.hasOwnProperty(p)) {\n if (keys[i] === '*' || p === keys[i]) {\n if (typeof val[p] === 'object' && !(val[p] instanceof Array)) {\n return valueMatchesKeyString(val[p], keys.slice(i + 1).join('.'));\n } else {\n return true;\n }\n }\n }\n i++;\n }\n return false;\n};\n\n// used to copy branches within the store. Object and array friendly\nclone = function (val) {\n var newObj, i, prop;\n if (val instanceof Array) {\n newObj = [];\n for (i = 0; i < val.length; i++) {\n newObj[i] = clone(val[i]);\n }\n } else if (typeof val === 'object') {\n newObj = {};\n for (prop in val) {\n if (val.hasOwnProperty(prop)) {\n newObj[prop] = clone(val[prop]);\n }\n }\n } else {\n return val;\n }\n return newObj;\n};\n\n// returns a value from a store given an array of keys that is meant to describe depth\n// within the storage tree\ngetValue = function (store, keys) {\n var key = keys.shift(),\n endKey,\n arrResult,\n p,\n keysClone;\n if (key === '*') {\n arrResult = [];\n for (p in store) {\n if (store.hasOwnProperty(p)) {\n keysClone = clone(keys);\n arrResult.push(getValue(store[p], keysClone));\n }\n }\n return arrResult;\n }\n if (keys[0] && store[key] && (store[key][keys[0]] || keys[0] === '*')) {\n return getValue(store[key], keys);\n } else {\n if (keys.length) {\n endKey = keys[0];\n } else {\n endKey = key;\n }\n return store[endKey];\n }\n};\n\ngenerateRandomId = function (length) {\n var text = \"\",\n i,\n possible = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n for (i = 0; i < length; i++) {\n text += possible.charAt(Math.floor(Math.random() * possible.length));\n }\n return text;\n};\n\ngetRandomId = function () {\n var id = generateRandomId(ID_LENGTH);\n // no duplicate ids allowed\n while (arrayContains(randoms, id)) {\n id = generateRandomId(ID_LENGTH);\n }\n randoms.push(id);\n return id;\n};\n\nmodule.exports = JSDS;\n\n//# sourceURL=webpack:///./src/jsds.js?"); + +/***/ }), + +/***/ 0: +/*!****************************!*\ + !*** multi ./src/index.js ***! + \****************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("module.exports = __webpack_require__(/*! ./src/index.js */\"./src/index.js\");\n\n\n//# sourceURL=webpack:///multi_./src/index.js?"); + +/***/ }) + +/******/ }); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2b1c489..c8f74d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,154 @@ { "name": "javascript-data-store", - "version": "1.0.0", + "version": "1.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.49.tgz", + "integrity": "sha1-vs2AVIJzREDJ0TfkbXc0DmTX9Rs=", + "dev": true, + "requires": { + "@babel/highlight": "7.0.0-beta.49" + } + }, + "@babel/generator": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.49.tgz", + "integrity": "sha1-6c/9qROZaszseTu8JauRvBnQv3o=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49", + "jsesc": "2.5.1", + "lodash": "4.17.10", + "source-map": "0.5.7", + "trim-right": "1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.49.tgz", + "integrity": "sha1-olwRGbnwNSeGcBJuAiXAMEHI3jI=", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "7.0.0-beta.49", + "@babel/template": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.49.tgz", + "integrity": "sha1-z1Aj8y0q2S0Ic3STnOwJUby1FEE=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.49.tgz", + "integrity": "sha1-QNeO2glo0BGxxShm5XRs+yPldUg=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.49" + } + }, + "@babel/highlight": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.49.tgz", + "integrity": "sha1-lr3GtD4TSCASumaRsQGEktOWIsw=", + "dev": true, + "requires": { + "chalk": "2.4.1", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "@babel/parser": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.0.0-beta.49.tgz", + "integrity": "sha1-lE0MW6KBK7FZ7b0iZ0Ov0mUXm9w=", + "dev": true + }, + "@babel/template": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.49.tgz", + "integrity": "sha1-44q+ghfLl5P0YaUwbXrXRdg+HSc=", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.49", + "@babel/parser": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49", + "lodash": "4.17.10" + } + }, + "@babel/traverse": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.49.tgz", + "integrity": "sha1-TypzaCoYM07WYl0QCo0nMZ98LWg=", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.49", + "@babel/generator": "7.0.0-beta.49", + "@babel/helper-function-name": "7.0.0-beta.49", + "@babel/helper-split-export-declaration": "7.0.0-beta.49", + "@babel/parser": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49", + "debug": "3.1.0", + "globals": "11.5.0", + "invariant": "2.2.4", + "lodash": "4.17.10" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@babel/types": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.49.tgz", + "integrity": "sha1-t+Oxw/TUz+Eb34yJ8e/V4WF7h6Y=", + "dev": true, + "requires": { + "esutils": "2.0.2", + "lodash": "4.17.10", + "to-fast-properties": "2.0.0" + } + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "1.0.1", + "glob-to-regexp": "0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.0.tgz", + "integrity": "sha512-LAQ1d4OPfSJ/BMbI2DuizmYrrkD9JMaTdi2hQTlI53lQ4kRQPyZQRS4CYQ7O66bnBBnP/oYdRxbk++X0xuFU6A==", + "dev": true + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "dev": true, + "requires": { + "any-observable": "0.3.0" + } + }, "@sindresorhus/is": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", @@ -65,9 +210,9 @@ } }, "any-observable": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.2.0.tgz", - "integrity": "sha1-xnhwBYADV5AJCD9UrAq6+1wz0kI=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", "dev": true }, "anymatch": { @@ -157,6 +302,12 @@ "util": "0.10.3" } }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -164,9 +315,9 @@ "dev": true }, "ast-types": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.3.tgz", - "integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==", + "version": "0.11.5", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", + "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", "dev": true }, "async": { @@ -241,9 +392,9 @@ } }, "babel-core": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", - "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "requires": { "babel-code-frame": "6.26.0", @@ -259,7 +410,7 @@ "convert-source-map": "1.5.1", "debug": "2.6.9", "json5": "0.5.1", - "lodash": "4.17.5", + "lodash": "4.17.10", "minimatch": "3.0.4", "path-is-absolute": "1.0.1", "private": "0.1.8", @@ -286,7 +437,7 @@ "babel-types": "6.26.0", "detect-indent": "4.0.0", "jsesc": "1.3.0", - "lodash": "4.17.5", + "lodash": "4.17.10", "source-map": "0.5.7", "trim-right": "1.0.1" }, @@ -342,7 +493,7 @@ "babel-helper-function-name": "6.24.1", "babel-runtime": "6.26.0", "babel-types": "6.26.0", - "lodash": "4.17.5" + "lodash": "4.17.10" } }, "babel-helper-explode-assignable-expression": { @@ -419,7 +570,7 @@ "requires": { "babel-runtime": "6.26.0", "babel-types": "6.26.0", - "lodash": "4.17.5" + "lodash": "4.17.10" } }, "babel-helper-remap-async-to-generator": { @@ -640,7 +791,7 @@ "babel-template": "6.26.0", "babel-traverse": "6.26.0", "babel-types": "6.26.0", - "lodash": "4.17.5" + "lodash": "4.17.10" } }, "babel-plugin-transform-es2015-classes": { @@ -724,15 +875,15 @@ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", "babel-runtime": "6.26.0", "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", - "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", "dev": true, "requires": { "babel-plugin-transform-strict-mode": "6.24.1", @@ -906,44 +1057,6 @@ "babel-types": "6.26.0" } }, - "babel-preset-env": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", - "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.26.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "babel-plugin-transform-regenerator": "6.26.0", - "browserslist": "2.11.3", - "invariant": "2.2.4", - "semver": "5.5.0" - } - }, "babel-preset-es2015": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", @@ -962,7 +1075,7 @@ "babel-plugin-transform-es2015-function-name": "6.24.1", "babel-plugin-transform-es2015-literals": "6.22.0", "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", "babel-plugin-transform-es2015-modules-umd": "6.24.1", "babel-plugin-transform-es2015-object-super": "6.24.1", @@ -1018,11 +1131,11 @@ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "dev": true, "requires": { - "babel-core": "6.26.0", + "babel-core": "6.26.3", "babel-runtime": "6.26.0", - "core-js": "2.5.5", + "core-js": "2.5.7", "home-or-tmp": "2.0.0", - "lodash": "4.17.5", + "lodash": "4.17.10", "mkdirp": "0.5.1", "source-map-support": "0.4.18" } @@ -1033,7 +1146,7 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.5", + "core-js": "2.5.7", "regenerator-runtime": "0.11.1" } }, @@ -1047,7 +1160,7 @@ "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", - "lodash": "4.17.5" + "lodash": "4.17.10" }, "dependencies": { "babylon": { @@ -1072,7 +1185,7 @@ "debug": "2.6.9", "globals": "9.18.0", "invariant": "2.2.4", - "lodash": "4.17.5" + "lodash": "4.17.10" }, "dependencies": { "babylon": { @@ -1080,6 +1193,12 @@ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true } } }, @@ -1091,14 +1210,22 @@ "requires": { "babel-runtime": "6.26.0", "esutils": "2.0.2", - "lodash": "4.17.5", + "lodash": "4.17.10", "to-fast-properties": "1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + } } }, "babylon": { - "version": "7.0.0-beta.44", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz", - "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==", + "version": "7.0.0-beta.47", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.47.tgz", + "integrity": "sha512-+rq2cr4GDhtToEzKFD6KZZMDBXhjFAr9JjPw9pAppZACeEWqNM294j+NdBzkSHYXwzzBmVjZ3nEVJlOhbR2gOQ==", "dev": true }, "balanced-match": { @@ -1243,6 +1370,12 @@ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", @@ -1313,16 +1446,6 @@ "pako": "1.0.6" } }, - "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", - "dev": true, - "requires": { - "caniuse-lite": "1.0.30000830", - "electron-to-chromium": "1.3.42" - } - }, "buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", @@ -1419,22 +1542,36 @@ } } }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true }, - "caniuse-lite": { - "version": "1.0.30000830", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000830.tgz", - "integrity": "sha512-yMqGkujkoOIZfvOYiWdqPALgY/PVGiqCHUJb6yNq7xhI/pR+gQO0U2K6lRDqAiJv4+CIU3CtTLblNGw0QGnr6g==", - "dev": true + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "1.1.0", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.8" + } }, "chalk": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz", - "integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { "ansi-styles": "3.2.1", @@ -1448,6 +1585,12 @@ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", "dev": true }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, "chokidar": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", @@ -1599,9 +1742,9 @@ "dev": true }, "cliui": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", - "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { "string-width": "2.1.1", @@ -1679,9 +1822,9 @@ "dev": true }, "colors": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz", - "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.0.tgz", + "integrity": "sha512-EDpX3a7wHMWFA7PUHWPHNWqOxIIRSJetuwl0AS5Oi/5FMV8kWm69RTlgm00GKjBO1xFHMtBbL49yRtMMdticBw==", "dev": true }, "commander": { @@ -1762,9 +1905,9 @@ "dev": true }, "core-js": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz", - "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", "dev": true }, "core-util-is": { @@ -1820,7 +1963,7 @@ "path-key": "2.0.1", "semver": "5.5.0", "shebang-command": "1.2.0", - "which": "1.3.0" + "which": "1.3.1" } }, "crypto-browserify": { @@ -1902,10 +2045,19 @@ "mimic-response": "1.0.0" } }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", "dev": true }, "define-property": { @@ -1991,6 +2143,16 @@ "randombytes": "2.0.6" } }, + "dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "dev": true, + "requires": { + "arrify": "1.0.1", + "path-type": "3.0.0" + } + }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", @@ -2022,15 +2184,9 @@ "dev": true }, "ejs": { - "version": "2.5.8", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.8.tgz", - "integrity": "sha512-QIDZL54fyV8MDcAsO91BMH1ft2qGGaHIJsJIA/+t+7uvXol1dm413fPcUgUb4k8F/9457rx4/KFE4XfDifrQxQ==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.42", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.42.tgz", - "integrity": "sha1-lcM78B0MxAVVauyJn+Yf1NduoPk=", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==", "dev": true }, "elegant-spinner": { @@ -2081,9 +2237,9 @@ } }, "envinfo": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-4.4.2.tgz", - "integrity": "sha512-5rfRs+m+6pwoKRCFqpsA5+qsLngFms1aWPrxfKbrObCzQaPc3M3yPloZx+BL9UE3dK58cxw36XVQbFRSCCfGSQ==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-5.10.0.tgz", + "integrity": "sha512-rXbzXWvnQxy+TcqZlARbWVQwgGVVouVJgFZhLVN5htjLxl1thstrP2ZGi0pXC309AbK7gVOPU+ulz/tmpCI7iw==", "dev": true }, "errno": { @@ -2196,7 +2352,7 @@ "requires": { "lru-cache": "4.1.2", "shebang-command": "1.2.0", - "which": "1.3.0" + "which": "1.3.1" } } } @@ -2248,18 +2404,18 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "2.2.3" + "fill-range": "2.2.4" }, "dependencies": { "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { "is-number": "2.1.0", "isobject": "2.1.0", - "randomatic": "1.1.7", + "randomatic": "3.0.0", "repeat-element": "1.1.2", "repeat-string": "1.6.1" } @@ -2330,7 +2486,7 @@ "dev": true, "requires": { "chardet": "0.4.2", - "iconv-lite": "0.4.21", + "iconv-lite": "0.4.23", "tmp": "0.0.33" } }, @@ -2405,6 +2561,20 @@ "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, + "fast-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.2.tgz", + "integrity": "sha512-TR6zxCKftDQnUAPvkrCWdBgDq/gbqx8A3ApnBrR5rMvpp6+KMJI0Igw7fkWPgeVK0uhRXTXdvO3O+YP0CaUX2g==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "2.2.1", + "@nodelib/fs.stat": "1.1.0", + "glob-parent": "3.1.0", + "is-glob": "4.0.0", + "merge2": "1.2.2", + "micromatch": "3.1.10" + } + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -2479,9 +2649,9 @@ } }, "flow-parser": { - "version": "0.70.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.70.0.tgz", - "integrity": "sha512-gGdyVUZWswG5jcINrVDHd3RY4nJptBTAx9mR9thGsrGGmAUR7omgJXQSpR+fXrLtxSTAea3HpAZNU/yzRJc2Cg==", + "version": "0.74.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.74.0.tgz", + "integrity": "sha512-iQHi88aFCkPLr8cW1L9FtP9lmiT/9g20YaycW6sSWX6U9EdwN6K6OkWBlLhrfG5rbDJfJ9k0npVSfAkGNR7x2Q==", "dev": true }, "flush-write-stream": { @@ -3456,6 +3626,12 @@ "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", "dev": true }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -3639,6 +3815,12 @@ } } }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -3660,40 +3842,34 @@ "homedir-polyfill": "1.0.1", "ini": "1.3.5", "is-windows": "1.0.2", - "which": "1.3.0" + "which": "1.3.1" } }, "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz", + "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==", "dev": true }, "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz", + "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==", "dev": true, "requires": { "array-union": "1.0.2", + "dir-glob": "2.0.0", + "fast-glob": "2.2.2", "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "ignore": "3.3.8", + "pify": "3.0.0", + "slash": "1.0.0" } }, "got": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/got/-/got-8.3.0.tgz", - "integrity": "sha512-kBNy/S2CGwrYgDSec5KTWGKUvupwkkTVAjIsVFF2shXO13xpZdFP4d4kxa//CLX2tN/rV0aYwK8vY6UKWGn2vQ==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.1.tgz", + "integrity": "sha512-tiLX+bnYm5A56T5N/n9Xo89vMaO1mrS9qoDqj3u/anVooqGozvY/HbXzEpDfbNeKsHCBpK40gSbz8wGYSp3i1w==", "dev": true, "requires": { "@sindresorhus/is": "0.7.0", @@ -3727,9 +3903,15 @@ "integrity": "sha1-wWfSpTGcWg4JZO9qJbfC34mWyFw=", "dev": true, "requires": { - "lodash": "4.17.5" + "lodash": "4.17.10" } }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -3826,6 +4008,12 @@ "minimalistic-assert": "1.0.1" } }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -3875,9 +4063,9 @@ "dev": true }, "iconv-lite": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", - "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { "safer-buffer": "2.1.2" @@ -3895,6 +4083,12 @@ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", "dev": true }, + "ignore": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", + "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", + "dev": true + }, "import-local": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", @@ -3955,15 +4149,15 @@ "dev": true, "requires": { "ansi-escapes": "3.1.0", - "chalk": "2.4.0", + "chalk": "2.4.1", "cli-cursor": "2.1.0", "cli-width": "2.2.0", "external-editor": "2.2.0", "figures": "2.0.0", - "lodash": "4.17.5", + "lodash": "4.17.10", "mute-stream": "0.0.7", "run-async": "2.3.0", - "rxjs": "5.5.10", + "rxjs": "5.5.11", "string-width": "2.1.1", "strip-ansi": "4.0.0", "through": "2.3.8" @@ -4167,18 +4361,18 @@ "dev": true }, "is-observable": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", - "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", "dev": true, "requires": { - "symbol-observable": "0.2.4" + "symbol-observable": "1.2.0" }, "dependencies": { "symbol-observable": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", - "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", "dev": true } } @@ -4272,6 +4466,12 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, + "isbinaryfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz", + "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4284,6 +4484,27 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "istanbul-lib-coverage": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz", + "integrity": "sha512-yMSw5xLIbdaxiVXHk3amfNM2WeBxLrwH/BCyZ9HvA/fylwziAIJOG2rKqWyLqEJqwKT725vxxqidv+SyynnGAA==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-2.2.0.tgz", + "integrity": "sha512-ozQGtlIw+/a/F3n6QwWiuuyRAPp64+g2GVsKYsIez0sgIEzkU5ZpL2uZ5pmAzbEJ82anlRaPlOQZzkRXspgJyg==", + "dev": true, + "requires": { + "@babel/generator": "7.0.0-beta.49", + "@babel/parser": "7.0.0-beta.49", + "@babel/template": "7.0.0-beta.49", + "@babel/traverse": "7.0.0-beta.49", + "@babel/types": "7.0.0-beta.49", + "istanbul-lib-coverage": "2.0.0", + "semver": "5.5.0" + } + }, "istextorbinary": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", @@ -4312,24 +4533,24 @@ "dev": true }, "jscodeshift": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.5.0.tgz", - "integrity": "sha512-JAcQINNMFpdzzpKJN8k5xXjF3XDuckB1/48uScSzcnNyK199iWEc9AxKL9OoX5144M2w5zEx9Qs4/E/eBZZUlw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.5.1.tgz", + "integrity": "sha512-sRMollbhbmSDrR79JMAnhEjyZJlQQVozeeY9A6/KNuV26DNcuB3mGSCWXp0hks9dcwRNOELbNOiwraZaXXRk5Q==", "dev": true, "requires": { "babel-plugin-transform-flow-strip-types": "6.22.0", "babel-preset-es2015": "6.24.1", "babel-preset-stage-1": "6.24.1", "babel-register": "6.26.0", - "babylon": "7.0.0-beta.44", - "colors": "1.2.1", - "flow-parser": "0.70.0", - "lodash": "4.17.5", + "babylon": "7.0.0-beta.47", + "colors": "1.3.0", + "flow-parser": "0.74.0", + "lodash": "4.17.10", "micromatch": "2.3.11", "neo-async": "2.5.1", "node-dir": "0.1.8", "nomnom": "1.8.1", - "recast": "0.14.7", + "recast": "0.15.0", "temp": "0.8.3", "write-file-atomic": "1.3.4" }, @@ -4426,9 +4647,9 @@ } }, "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz", + "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", "dev": true }, "json-buffer": { @@ -4480,16 +4701,16 @@ } }, "listr": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/listr/-/listr-0.13.0.tgz", - "integrity": "sha1-ILsLowuuZg7oTMBQPfS+PVYjiH0=", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.1.tgz", + "integrity": "sha512-MSMUUVN1f8aRnPi4034RkOqdiUlpYW+FqwFE3aL0uYNPRavkt2S2SsSpDDofn8BDpqv2RNnsdOcCHWsChcq77A==", "dev": true, "requires": { - "chalk": "1.1.3", + "@samverschueren/stream-to-observable": "0.3.0", "cli-truncate": "0.2.1", "figures": "1.7.0", "indent-string": "2.1.0", - "is-observable": "0.2.0", + "is-observable": "1.1.0", "is-promise": "2.1.0", "is-stream": "1.1.0", "listr-silent-renderer": "1.1.1", @@ -4499,8 +4720,7 @@ "log-update": "1.0.2", "ora": "0.2.3", "p-map": "1.2.0", - "rxjs": "5.5.10", - "stream-to-observable": "0.2.0", + "rxjs": "6.2.0", "strip-ansi": "3.0.1" }, "dependencies": { @@ -4548,6 +4768,15 @@ "chalk": "1.1.3" } }, + "rxjs": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.0.tgz", + "integrity": "sha512-qBzf5uu6eOKiCZuAE0SgZ0/Qp+l54oeVxFfC2t+mJ2SFI6IB8gmMdJHs5DUMu5kqifqcCtsKS2XHjhZu6RKvAw==", + "dev": true, + "requires": { + "tslib": "1.9.2" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -4791,9 +5020,9 @@ } }, "lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", "dev": true }, "log-symbols": { @@ -4802,7 +5031,7 @@ "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, "requires": { - "chalk": "2.4.0" + "chalk": "2.4.1" } }, "log-update": { @@ -4897,6 +5126,12 @@ "object-visit": "1.0.1" } }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "dev": true + }, "md5.js": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", @@ -4928,16 +5163,17 @@ } }, "mem-fs-editor": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-3.0.2.tgz", - "integrity": "sha1-3Qpuryu4prN3QAZ6pUnrUwEFr58=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-4.0.2.tgz", + "integrity": "sha512-QHvdXLLNmwJXxKdf7x27aNUren6IoPxwcM8Sfd+S6/ddQQMcYdEtVKsh6ilpqMrU18VQuKZEaH0aCGt3JDbA0g==", "dev": true, "requires": { "commondir": "1.0.1", - "deep-extend": "0.4.2", - "ejs": "2.5.8", + "deep-extend": "0.5.1", + "ejs": "2.6.1", "glob": "7.1.2", - "globby": "6.1.0", + "globby": "8.0.1", + "isbinaryfile": "3.0.2", "mkdirp": "0.5.1", "multimatch": "2.1.0", "rimraf": "2.6.2", @@ -4946,9 +5182,9 @@ }, "dependencies": { "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", "dev": true }, "clone-stats": { @@ -4969,7 +5205,7 @@ "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", "dev": true, "requires": { - "clone": "2.1.2", + "clone": "2.1.1", "clone-buffer": "1.0.0", "clone-stats": "1.0.0", "cloneable-readable": "1.1.2", @@ -4989,6 +5225,12 @@ "readable-stream": "2.3.6" } }, + "merge2": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.2.tgz", + "integrity": "sha512-bgM8twH86rWni21thii6WCMQMRMmwqqdW3sGWi9IipnVAszdLXRjwDwAnyrVXo6DuP3AjRMMttZKUB48QWIFGg==", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -5107,6 +5349,42 @@ "minimist": "0.0.8" } }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -5311,23 +5589,2076 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "nyc": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-12.0.2.tgz", + "integrity": "sha1-ikpO1pCWbBHsWH/4fuoMEsl0upk=", "dev": true, "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" - }, - "dependencies": { + "archy": "1.0.0", + "arrify": "1.0.1", + "caching-transform": "1.0.1", + "convert-source-map": "1.5.1", + "debug-log": "1.0.1", + "default-require-extensions": "1.0.0", + "find-cache-dir": "0.1.1", + "find-up": "2.1.0", + "foreground-child": "1.5.6", + "glob": "7.1.2", + "istanbul-lib-coverage": "1.2.0", + "istanbul-lib-hook": "1.1.0", + "istanbul-lib-instrument": "2.2.0", + "istanbul-lib-report": "1.1.3", + "istanbul-lib-source-maps": "1.2.5", + "istanbul-reports": "1.4.1", + "md5-hex": "1.3.0", + "merge-source-map": "1.1.0", + "micromatch": "3.1.10", + "mkdirp": "0.5.1", + "resolve-from": "2.0.0", + "rimraf": "2.6.2", + "signal-exit": "3.0.2", + "spawn-wrap": "1.4.2", + "test-exclude": "4.2.1", + "yargs": "11.1.0", + "yargs-parser": "8.1.0" + }, + "dependencies": { + "align-text": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "amdefine": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "1.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "bundled": true, + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "async": { + "version": "1.5.2", + "bundled": true, + "dev": true + }, + "atob": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "base": { + "version": "0.11.2", + "bundled": true, + "dev": true, + "requires": { + "cache-base": "1.0.1", + "class-utils": "0.3.6", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.1", + "pascalcase": "0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "requires": { + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "repeat-element": "1.1.2", + "snapdragon": "0.8.2", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" + } + }, + "caching-transform": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "md5-hex": "1.3.0", + "mkdirp": "0.5.1", + "write-file-atomic": "1.3.4" + } + }, + "camelcase": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true + }, + "center-align": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "class-utils": { + "version": "0.3.6", + "bundled": true, + "dev": true, + "requires": { + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "static-extend": "0.1.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + } + } + }, + "cliui": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-visit": "1.0.0", + "object-visit": "1.0.1" + } + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.5.1", + "bundled": true, + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "4.1.3", + "which": "1.3.1" + } + }, + "debug": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "debug-log": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "2.0.0" + } + }, + "define-property": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2", + "isobject": "3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "error-ex": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "execa": { + "version": "0.7.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "4.1.3", + "shebang-command": "1.2.0", + "which": "1.3.1" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "requires": { + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "extend-shallow": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "fill-range": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "find-cache-dir": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "requires": { + "commondir": "1.0.1", + "mkdirp": "0.5.1", + "pkg-dir": "1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "4.0.2", + "signal-exit": "3.0.2" + } + }, + "fragment-cache": { + "version": "0.2.1", + "bundled": true, + "dev": true, + "requires": { + "map-cache": "0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "get-value": { + "version": "2.0.6", + "bundled": true, + "dev": true + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.11", + "bundled": true, + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "bundled": true, + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "has-value": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" + } + }, + "has-values": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "hosted-git-info": { + "version": "2.6.0", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-number": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-odd": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-number": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "bundled": true, + "dev": true + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "0.4.0" + } + }, + "istanbul-lib-report": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "1.2.0", + "mkdirp": "0.5.1", + "path-parse": "1.0.5", + "supports-color": "3.2.3" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "requires": { + "debug": "3.1.0", + "istanbul-lib-coverage": "1.2.0", + "mkdirp": "0.5.1", + "rimraf": "2.6.2", + "source-map": "0.5.7" + } + }, + "istanbul-reports": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "4.0.11" + } + }, + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "lazy-cache": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "lcid": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + } + } + }, + "longest": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.3", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "map-cache": { + "version": "0.2.2", + "bundled": true, + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "object-visit": "1.0.1" + } + }, + "md5-hex": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "md5-o-matic": "0.1.1" + } + }, + "md5-o-matic": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "mem": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "mimic-fn": "1.2.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "micromatch": { + "version": "3.1.10", + "bundled": true, + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.9", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "for-in": "1.0.2", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "nanomatch": { + "version": "1.2.9", + "bundled": true, + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "fragment-cache": "0.2.1", + "is-odd": "2.0.0", + "is-windows": "1.0.2", + "kind-of": "6.0.2", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "2.6.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "requires": { + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "object.pick": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "1.2.0" + } + }, + "p-try": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "pascalcase": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pify": { + "version": "2.3.0", + "bundled": true, + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "bundled": true, + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-dir": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "1.1.2" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + } + } + }, + "regex-not": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" + } + }, + "repeat-element": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "bundled": true, + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "ret": { + "version": "0.1.15", + "bundled": true, + "dev": true + }, + "right-align": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-regex": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "ret": "0.1.15" + } + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "set-value": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "slide": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "requires": { + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.2", + "use": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "source-map": { + "version": "0.5.7", + "bundled": true, + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "bundled": true, + "dev": true, + "requires": { + "atob": "2.1.1", + "decode-uri-component": "0.2.0", + "resolve-url": "0.2.1", + "source-map-url": "0.4.0", + "urix": "0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "1.5.6", + "mkdirp": "0.5.1", + "os-homedir": "1.0.2", + "rimraf": "2.6.2", + "signal-exit": "3.0.2", + "which": "1.3.1" + } + }, + "spdx-correct": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "split-string": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "3.0.2" + } + }, + "static-extend": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "requires": { + "define-property": "0.2.5", + "object-copy": "0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + } + } + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "arrify": "1.0.1", + "micromatch": "3.1.10", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "require-main-filename": "1.0.1" + } + }, + "to-object-path": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "to-regex": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-number": "3.0.0", + "repeat-string": "1.6.1" + } + }, + "uglify-js": { + "version": "2.8.29", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "union-value": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "set-value": { + "version": "0.4.3", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" + } + } + } + }, + "unset-value": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "has-value": "0.3.1", + "isobject": "3.0.1" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "bundled": true, + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "bundled": true, + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "bundled": true, + "dev": true + }, + "use": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "validate-npm-package-license": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "window-size": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "slide": "1.1.6" + } + }, + "y18n": { + "version": "3.2.1", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "11.1.0", + "bundled": true, + "dev": true, + "requires": { + "cliui": "4.1.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "9.0.2" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" + } + }, + "yargs-parser": { + "version": "9.0.2", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "8.1.0", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "bundled": true, + "dev": true + } + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" + }, + "dependencies": { "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -5706,6 +8037,12 @@ "pify": "3.0.0" } }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, "pbkdf2": { "version": "3.0.14", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", @@ -5768,9 +8105,9 @@ "dev": true }, "prettier": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.12.1.tgz", - "integrity": "sha1-wa0g6APndJ+vkFpAnSNn4Gu+cyU=", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.13.4.tgz", + "integrity": "sha512-emsEZ2bAigL1lq6ssgkpPm1MIBqgeTvcp90NxOP5XDqprub/V/WS2Hfgih3mS7/1dqTUvhG+sxx1Dv8crnVexA==", "dev": true }, "pretty-bytes": { @@ -5879,23 +8216,21 @@ "dev": true }, "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", + "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "4.0.0", + "kind-of": "6.0.2", + "math-random": "1.0.1" }, "dependencies": { - "kind-of": { + "is-number": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true } } }, @@ -5977,12 +8312,12 @@ } }, "recast": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.14.7.tgz", - "integrity": "sha512-/nwm9pkrcWagN40JeJhkPaRxiHXBRkXyRh/hgU088Z/v+qCy+zIHHY6bC6o7NaKAxPqtE6nD8zBH1LfU0/Wx6A==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.15.0.tgz", + "integrity": "sha512-47C2mIxQYvFICrTNuV4+xGgBa1nAoq42ANN5oDTSBIJ50NX7jcki7gAC6HWYptnQgHmqIRTHJq8OKdi3fwgyNQ==", "dev": true, "requires": { - "ast-types": "0.11.3", + "ast-types": "0.11.5", "esprima": "4.0.0", "private": "0.1.8", "source-map": "0.6.1" @@ -6006,9 +8341,9 @@ } }, "regenerate": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", - "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", "dev": true }, "regenerator-runtime": { @@ -6053,7 +8388,7 @@ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "dev": true, "requires": { - "regenerate": "1.3.3", + "regenerate": "1.4.0", "regjsgen": "0.2.0", "regjsparser": "0.1.5" } @@ -6071,6 +8406,14 @@ "dev": true, "requires": { "jsesc": "0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } } }, "remove-trailing-separator": { @@ -6231,25 +8574,10 @@ "aproba": "1.2.0" } }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "4.0.8" - } - }, "rxjs": { - "version": "5.5.10", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.10.tgz", - "integrity": "sha512-SRjimIDUHJkon+2hFo7xnvNC4ZEHGzCRwh9P7nzX3zPkCGFEg/tuElrNR7L/rZMagnK2JeH2jQwPRpmyXyLB6A==", + "version": "5.5.11", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.11.tgz", + "integrity": "sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA==", "dev": true, "requires": { "symbol-observable": "1.0.1" @@ -6371,9 +8699,9 @@ "dev": true }, "shelljs": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.1.tgz", - "integrity": "sha512-YA/iYtZpzFe5HyWVGrb02FjPxc4EMCfpoU/Phg9fQoyMC72u9598OUBrsU8IrtwAKG0tO8IYaqbaLIw+k3IRGA==", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.2.tgz", + "integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==", "dev": true, "requires": { "glob": "7.1.2", @@ -6671,15 +8999,6 @@ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "dev": true }, - "stream-to-observable": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.2.0.tgz", - "integrity": "sha1-WdbqOT2HwsDdrBCqDVYbxrpvDhA=", - "dev": true, - "requires": { - "any-observable": "0.2.0" - } - }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -6843,9 +9162,9 @@ "dev": true }, "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "to-object-path": { @@ -6896,12 +9215,24 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "tslib": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.2.tgz", + "integrity": "sha512-AVP5Xol3WivEr7hnssHDsaM+lVrVXWUvd1cfXTRkTj80b//6g2wIFEH6hZG0muGZRnHGrfttpdzRk3YlBkWjKw==", + "dev": true + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -7050,9 +9381,9 @@ } }, "untildify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.2.tgz", - "integrity": "sha1-fx8wIFWz/qDz6B3HjrNnZstl4/E=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.3.tgz", + "integrity": "sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==", "dev": true }, "upath": { @@ -7142,9 +9473,9 @@ "dev": true }, "v8-compile-cache": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz", - "integrity": "sha512-ejdrifsIydN1XDH7EuR2hn8ZrkRKUYF7tUcBjBy/lhrCvs2K+zRlbW9UHc0IQ9RsYFZJFqJrieoIHfkCa0DBRA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.0.tgz", + "integrity": "sha512-qNdTUMaCjPs4eEnM3W9H94R3sU70YCuT+/ST7nUf+id1bVOrdjrpUaeZLqPBPRph3hsgn4a4BvwpxhHZx+oSDg==", "dev": true }, "validate-npm-package-license": { @@ -7329,9 +9660,9 @@ "babel-preset-stage-1": "6.24.1", "babel-register": "6.26.0", "babylon": "6.18.0", - "colors": "1.2.1", - "flow-parser": "0.70.0", - "lodash": "4.17.5", + "colors": "1.3.0", + "flow-parser": "0.74.0", + "lodash": "4.17.10", "micromatch": "2.3.11", "node-dir": "0.1.8", "nomnom": "1.8.1", @@ -7377,7 +9708,7 @@ "dev": true, "requires": { "ast-types": "0.10.1", - "core-js": "2.5.5", + "core-js": "2.5.7", "esprima": "4.0.0", "private": "0.1.8", "source-map": "0.6.1" @@ -7392,37 +9723,37 @@ } }, "webpack-cli": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-2.0.14.tgz", - "integrity": "sha512-gRoWaxSi2JWiYsn1QgOTb6ENwIeSvN1YExZ+kJ0STsTZK7bWPElW+BBBv1UnTbvcPC3v7E17mK8hlFX8DOYSGw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-2.1.5.tgz", + "integrity": "sha512-CiWQR+1JS77rmyiO6y1q8Kt/O+e8nUUC9YfJ25JtSmzDwbqJV7vIsh3+QKRHVTbTCa0DaVh8iY1LBiagUIDB3g==", "dev": true, "requires": { - "chalk": "2.4.0", + "chalk": "2.4.1", "cross-spawn": "6.0.5", "diff": "3.5.0", "enhanced-resolve": "4.0.0", - "envinfo": "4.4.2", + "envinfo": "5.10.0", "glob-all": "3.1.0", "global-modules": "1.0.0", - "got": "8.3.0", + "got": "8.3.1", "import-local": "1.0.0", "inquirer": "5.2.0", "interpret": "1.1.0", - "jscodeshift": "0.5.0", - "listr": "0.13.0", + "jscodeshift": "0.5.1", + "listr": "0.14.1", "loader-utils": "1.1.0", - "lodash": "4.17.5", + "lodash": "4.17.10", "log-symbols": "2.2.0", "mkdirp": "0.5.1", "p-each-series": "1.0.0", "p-lazy": "1.0.0", - "prettier": "1.12.1", + "prettier": "1.13.4", "supports-color": "5.4.0", - "v8-compile-cache": "1.1.2", + "v8-compile-cache": "2.0.0", "webpack-addons": "1.1.5", "yargs": "11.1.0", - "yeoman-environment": "2.0.6", - "yeoman-generator": "2.0.4" + "yeoman-environment": "2.2.0", + "yeoman-generator": "2.0.5" } }, "webpack-sources": { @@ -7444,9 +9775,9 @@ } }, "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { "isexe": "2.0.0" @@ -7555,7 +9886,7 @@ "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "dev": true, "requires": { - "cliui": "4.0.0", + "cliui": "4.1.0", "decamelize": "1.2.0", "find-up": "2.1.0", "get-caller-file": "1.0.2", @@ -7587,24 +9918,26 @@ } }, "yeoman-environment": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.0.6.tgz", - "integrity": "sha512-jzHBTTy8EPI4ImV8dpUMt+Q5zELkSU5xvGpndHcHudQ4tqN6YgIWaCGmRFl+HDchwRUkcgyjQ+n6/w5zlJBCPg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.2.0.tgz", + "integrity": "sha512-gQ+hIW8QRlUo4jGBDCm++qg01SXaIVJ7VyLrtSwk2jQG4vtvluWpsGIl7V8DqT2jGiqukdec0uEyffVEyQgaZA==", "dev": true, "requires": { - "chalk": "2.4.0", + "chalk": "2.4.1", + "cross-spawn": "6.0.5", "debug": "3.1.0", "diff": "3.5.0", "escape-string-regexp": "1.0.5", - "globby": "6.1.0", + "globby": "8.0.1", "grouped-queue": "0.3.3", - "inquirer": "3.3.0", + "inquirer": "5.2.0", "is-scoped": "1.0.0", - "lodash": "4.17.5", + "lodash": "4.17.10", "log-symbols": "2.2.0", "mem-fs": "1.1.3", + "strip-ansi": "4.0.0", "text-table": "0.2.0", - "untildify": "3.0.2" + "untildify": "3.0.3" }, "dependencies": { "debug": { @@ -7615,41 +9948,19 @@ "requires": { "ms": "2.0.0" } - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "3.1.0", - "chalk": "2.4.0", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "2.2.0", - "figures": "2.0.0", - "lodash": "4.17.5", - "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rx-lite": "4.0.8", - "rx-lite-aggregates": "4.0.8", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" - } } } }, "yeoman-generator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-2.0.4.tgz", - "integrity": "sha512-Sgvz3MAkOpEIobcpW3rjEl6bOTNnl8SkibP9z7hYKfIGIlw0QDC2k0MAeXvyE2pLqc2M0Duql+6R7/W9GrJojg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-2.0.5.tgz", + "integrity": "sha512-rV6tJ8oYzm4mmdF2T3wjY+Q42jKF2YiiD0VKfJ8/0ZYwmhCKC9Xs2346HVLPj/xE13i68psnFJv7iS6gWRkeAg==", "dev": true, "requires": { - "async": "2.6.0", - "chalk": "2.4.0", + "async": "2.6.1", + "chalk": "2.4.1", "cli-table": "0.3.1", - "cross-spawn": "5.1.0", + "cross-spawn": "6.0.5", "dargs": "5.1.0", "dateformat": "3.0.3", "debug": "3.1.0", @@ -7658,39 +9969,28 @@ "find-up": "2.1.0", "github-username": "4.1.0", "istextorbinary": "2.2.1", - "lodash": "4.17.5", + "lodash": "4.17.10", "make-dir": "1.2.0", - "mem-fs-editor": "3.0.2", + "mem-fs-editor": "4.0.2", "minimist": "1.2.0", "pretty-bytes": "4.0.2", "read-chunk": "2.1.0", "read-pkg-up": "3.0.0", "rimraf": "2.6.2", "run-async": "2.3.0", - "shelljs": "0.8.1", + "shelljs": "0.8.2", "text-table": "0.2.0", "through2": "2.0.3", - "yeoman-environment": "2.0.6" + "yeoman-environment": "2.2.0" }, "dependencies": { "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "dev": true, - "requires": { - "lodash": "4.17.5" - } - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lru-cache": "4.1.2", - "shebang-command": "1.2.0", - "which": "1.3.0" + "lodash": "4.17.10" } }, "debug": { diff --git a/package.json b/package.json index ac120eb..e4c7923 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "javascript-data-store", - "version": "1.0.0", + "version": "1.0.3", "description": "JSDS is a small and fast data store.", - "main": "webpack.config.js", "directories": { "test": "tests" }, "scripts": { - "start": "webpack --config webpack.config.js" + "test": "nyc --reporter=html --reporter=text mocha tests --recursive", + "start": "./node_modules/.bin/webpack" }, "repository": { "type": "git", @@ -26,12 +26,12 @@ "url": "https://github.com/rhyolight/JavaScript-Data-Store/issues" }, "homepage": "https://github.com/rhyolight/JavaScript-Data-Store#readme", - "dependencies": {}, "devDependencies": { - "babel-core": "^6.26.0", "babel-loader": "^7.1.4", - "babel-preset-env": "^1.6.1", + "chai": "^4.1.2", + "mocha": "^5.2.0", + "nyc": "^12.0.2", "webpack": "^4.6.0", - "webpack-cli": "^2.0.14" + "webpack-cli": "^2.0.15" } } diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..8e64947 --- /dev/null +++ b/src/index.js @@ -0,0 +1 @@ +window.JSDS = require('./jsds') diff --git a/src/jsds.js b/src/jsds.js index 4b90418..d1fb4f2 100755 --- a/src/jsds.js +++ b/src/jsds.js @@ -20,604 +20,592 @@ * THE SOFTWARE. */ -(function() { - var REGEX_DOT_G = /\./g, - BSLASH_DOT = '\.', - REGEX_STAR_G = /\*/g, - ID_LENGTH = 16, - // static export - JSDS, - // private props - randoms = [], - // private functions - storeIt, - update, - mergeArraysIntoSet, - arrayContains, - arrayRemoveItem, - fire, - listenerApplies, - removeListener, - getCompleteKey, - pullOutKeys, - toRegex, - valueMatchesKeyString, - clone, - getValue, - getRandomId, - generateRandomId; - - /*************************/ - /* The JSDataStore Class */ - /*************************/ - - function JSDataStore(id) { - // data stores - this._s = {}; - // event listeners - this._l = {}; - this.id = id; - } +var REGEX_DOT_G = /\./g, + BSLASH_DOT = '\.', + REGEX_STAR_G = /\*/g, + ID_LENGTH = 16, + // static export + JSDS, + // private props + randoms = [], + // private functions + storeIt, + update, + mergeArraysIntoSet, + arrayContains, + arrayRemoveItem, + fire, + listenerApplies, + removeListener, + getCompleteKey, + pullOutKeys, + toRegex, + valueMatchesKeyString, + clone, + getValue, + getRandomId, + generateRandomId; + +/*************************/ +/* The JSDataStore Class */ +/*************************/ + +function JSDataStore(id) { + // data stores + this._s = {}; + // event listeners + this._l = {}; + this.id = id; +} + +JSDataStore.prototype = { + + /** + * Stores data + * + * key {String}: the key to be used to store the data. The same key can be used to retrieve + * the data + * val {Object}: Any value to be stored in the store + * opts {Object} (optional): options to be used when storing data: + * 'update': if true, values already existing within objects and + * arrays will not be clobbered + * returns {Object}: The last value stored within specified key or undefined + * + * (fires 'store' event) + */ + set: function(key, val, opts /*optional*/) { + var result; + opts = opts || { update: false }; + fire.call(this, 'set', { + key: key, + value: val, + id: this.id, + when: 'before', + args: Array.prototype.slice.call(arguments, 0, arguments.length) + }); + result = storeIt(this._s, key, opts, val); + fire.call(this, 'set', { + key: key, + value: val, + id: this.id, + when: 'after', + result: this.get(key, {quiet: true}) + }); + return result; + }, + + /** + * Gets data back out of store + * + * key {String}: the key of the data you want back + * returns {Object}: the data or undefined if key doesn't exist + * + * (fires 'get' event) + */ + get: function(key) { + var s = this._s, keys, i=0, j=0, opts, result, splitKeys, + args = Array.prototype.slice.call(arguments, 0, arguments.length); + + opts = args[args.length-1]; + if (typeof opts === 'string') { + opts = {}; + } else { + args.pop(); + } - JSDataStore.prototype = { - - /** - * Stores data - * - * key {String}: the key to be used to store the data. The same key can be used to retrieve - * the data - * val {Object}: Any value to be stored in the store - * opts {Object} (optional): options to be used when storing data: - * 'update': if true, values already existing within objects and - * arrays will not be clobbered - * returns {Object}: The last value stored within specified key or undefined - * - * (fires 'store' event) - */ - set: function(key, val, opts /*optional*/) { - var result; - opts = opts || { update: false }; - fire.call(this, 'set', { + if (! opts.quiet) { + fire.call(this, 'get', { key: key, - value: val, - id: this.id, when: 'before', - args: Array.prototype.slice.call(arguments, 0, arguments.length) + args: args }); - result = storeIt(this._s, key, opts, val); - fire.call(this, 'set', { - key: key, - value: val, - id: this.id, - when: 'after', - result: this.get(key, {quiet: true}) - }); - return result; - }, - - /** - * Gets data back out of store - * - * key {String}: the key of the data you want back - * returns {Object}: the data or undefined if key doesn't exist - * - * (fires 'get' event) - */ - get: function(key) { - var s = this._s, keys, i=0, j=0, opts, result, splitKeys, - args = Array.prototype.slice.call(arguments, 0, arguments.length); - - opts = args[args.length-1]; - if (typeof opts === 'string') { - opts = {}; - } else { - args.pop(); - } - - if (! opts.quiet) { - fire.call(this, 'get', { - key: key, - when: 'before', - args: args - }); - } + } - if (args.length === 1 && key.indexOf(BSLASH_DOT) < 0) { - result = s[key]; - } else { - if (args.length > 1) { - keys = []; - for (i=0; i -1) { - splitKeys = args[i].split(BSLASH_DOT); - for (j=0; j 1) { + keys = []; + for (i=0; i -1) { + splitKeys = args[i].split(BSLASH_DOT); + for (j=0; j -1) { - keys = key.split(BSLASH_DOT); } - - result = getValue(s, keys); + } else if (key.indexOf(BSLASH_DOT) > -1) { + keys = key.split(BSLASH_DOT); } - if (! opts.quiet) { - fire.call(this, 'get', { - key:key, - value: result, - when: 'after', - result: result - }); - } - return result; - }, - - /** - * Adds a listener to this store. The listener will be executed when an event of - * the specified type is emitted and all the conditions defined in the parameters - * are met. - * - * type {String}: the type of event to listen for ('store', 'get', 'clear', etc.) - * options {object}: an object that contains one or more of the following configurations: - * 'callback': the function to be executed - * 'scope': the scope object for the callback execution - * 'key': the storage key to listen for. If specified only stores into this key will - * cause callback to be executed - * 'when': 'before' or 'after' (default is 'after') - */ - on: function(type, opts) { - var me = this, - cbid = getRandomId(), - key = opts.key, - fn = opts.callback, - scope = opts.scope || this, - when = opts.when || 'after'; - if (!this._l[type]) { - this._l[type] = []; - } - this._l[type].push({id: cbid, callback:fn, scope:scope, key: key, when: when}); - return { - id: cbid, - remove: function() { - removeListener(me._l[type], cbid); - } - }; - }, - - before: function(type, key, cb, scpe) { - var callback = cb, scope = scpe; - // key is optional - if (typeof key === 'function') { - callback = key; - scope = cb; - key = undefined; - } - return this.on(type, { - callback: callback, - key: key, - when: 'before', - scope: scope - }); - }, - - after: function(type, key, cb, scpe) { - var callback = cb, scope = scpe; - // key is optional - if (typeof key === 'function') { - callback = key; - scope = cb; - key = undefined; - } - return this.on(type, { - callback: callback, - key: key, + result = getValue(s, keys); + } + + if (! opts.quiet) { + fire.call(this, 'get', { + key:key, + value: result, when: 'after', - scope: scope + result: result }); - }, - - /** - * Removes all data from store - * - * (fires 'clear' event) - */ - clear: function() { - this._s = {}; - fire.call(this, 'clear'); - }, - - /** - * Removes all internal references to this data store. Note that to entirely release - * store object for garbage collection, you must also set any local references to the - * store to null! - * - * (fires 'remove' and 'clear' events) - */ - remove: function() { - var ltype, optsArray, opts, i; - this.clear(); - delete JSDS._stores[this.id]; - arrayRemoveItem(randoms, this.id); - fire.call(this, 'remove'); } - }; + return result; + }, + + /** + * Adds a listener to this store. The listener will be executed when an event of + * the specified type is emitted and all the conditions defined in the parameters + * are met. + * + * type {String}: the type of event to listen for ('set', 'get', 'clear', etc.) + * options {object}: an object that contains one or more of the following configurations: + * 'callback': the function to be executed + * 'scope': the scope object for the callback execution + * 'key': the storage key to listen for. If specified only stores into this key will + * cause callback to be executed + * 'when': 'before' or 'after' (default is 'after') + */ + on: function(type, opts) { + var me = this, + cbid = getRandomId(), + key = opts.key, + fn = opts.callback, + scope = opts.scope || this, + when = opts.when || 'after'; + if (!this._l[type]) { + this._l[type] = []; + } + this._l[type].push({id: cbid, callback:fn, scope:scope, key: key, when: when}); + return { + id: cbid, + remove: function() { + removeListener(me._l[type], cbid); + } + }; + }, + + before: function(type, key, cb, scpe) { + var callback = cb, scope = scpe; + // key is optional + if (typeof key === 'function') { + callback = key; + scope = cb; + key = undefined; + } + return this.on(type, { + callback: callback, + key: key, + when: 'before', + scope: scope + }); + }, + + after: function(type, key, cb, scpe) { + var callback = cb, scope = scpe; + // key is optional + if (typeof key === 'function') { + callback = key; + scope = cb; + key = undefined; + } + return this.on(type, { + callback: callback, + key: key, + when: 'after', + scope: scope + }); + }, + + /** + * Removes all data from store + * + * (fires 'clear' event) + */ + clear: function() { + this._s = {}; + fire.call(this, 'clear'); + }, + + /** + * Removes all internal references to this data store. Note that to entirely release + * store object for garbage collection, you must also set any local references to the + * store to null! + * + * (fires 'remove' and 'clear' events) + */ + remove: function() { + var ltype, optsArray, opts, i; + this.clear(); + delete JSDS._stores[this.id]; + arrayRemoveItem(randoms, this.id); + fire.call(this, 'remove'); + } +}; - /*************************/ - /* Global JSDS namespace */ - /*************************/ +/*************************/ +/* Global JSDS namespace */ +/*************************/ - JSDS = { +JSDS = { - _stores: {}, + _stores: {}, - /** - * Create a new data store object. If no id is specified, a random id will be - * generated. - * - * id {String} (optional): to identify this store for events and later retrieval - */ - create: function(id) { + /** + * Create a new data store object. If no id is specified, a random id will be + * generated. + * + * id {String} (optional): to identify this store for events and later retrieval + */ + create: function(id) { - id = id || getRandomId(); + id = id || getRandomId(); - if (this._stores[id]) { - throw new Error('Cannot overwrite existing data store "' + id + '"!'); - } + if (this._stores[id]) { + throw new Error('Cannot overwrite existing data store "' + id + '"!'); + } - this._stores[id] = new JSDataStore(id); - - return this._stores[id]; - }, - - /** - * Retrieves an existing data store object by id - * - * id {String}: the id of the store to retrieve - * returns {JSDataStore} the data store - */ - get: function(id) { - return this._stores[id]; - }, - - /** - * Removes all data stores objects. Specifically, each JSDataStore object's remove() - * method is called, and all local references to each are deleted. - */ - clear: function() { - var storeId; - for (storeId in this._stores) { - if (this._stores.hasOwnProperty(storeId)) { - this._stores[storeId].remove(); - delete this._stores[storeId]; - } + this._stores[id] = new JSDataStore(id); + + return this._stores[id]; + }, + + /** + * Retrieves an existing data store object by id + * + * id {String}: the id of the store to retrieve + * returns {JSDataStore} the data store + */ + get: function(id) { + return this._stores[id]; + }, + + /** + * Removes all data stores objects. Specifically, each JSDataStore object's remove() + * method is called, and all local references to each are deleted. + */ + clear: function() { + var storeId; + for (storeId in this._stores) { + if (this._stores.hasOwnProperty(storeId)) { + this._stores[storeId].remove(); + delete this._stores[storeId]; } - this._stores = {}; - }, - - /** - * Returns a count of the existing data stores in memory - */ - count: function() { - var cnt = 0, p; - for (p in this._stores) { - if (this._stores.hasOwnProperty(p)) { - cnt++; - } - } - return cnt; - }, - - /** - * Returns a list of ids [String] for all data store obects in memory - */ - ids: function() { - var id, ids = []; - for (id in this._stores) { - if (this._stores.hasOwnProperty(id)) { - ids.push(id); - } + } + this._stores = {}; + }, + + /** + * Returns a count of the existing data stores in memory + */ + count: function() { + var cnt = 0, p; + for (p in this._stores) { + if (this._stores.hasOwnProperty(p)) { + cnt++; } - return ids; } - }; - - /*****************/ - /* PRIVATE STUFF */ - /*****************/ - - // recursive store function - storeIt = function(store, key, opts, val, oldVal /*optional*/) { - var result, keys, oldKey; - if (key.indexOf(BSLASH_DOT) >= 0) { - keys = key.split('.'); - oldVal = store[keys[0]] ? clone(store[keys[0]]) : undefined; - oldKey = keys.shift(); - if (store[oldKey] === undefined) { - store[oldKey] = {}; + return cnt; + }, + + /** + * Returns a list of ids [String] for all data store obects in memory + */ + ids: function() { + var id, ids = []; + for (id in this._stores) { + if (this._stores.hasOwnProperty(id)) { + ids.push(id); } - return storeIt(store[oldKey], keys.join('.'), opts, val, oldVal); } - result = oldVal ? oldVal[key] : store[key]; - // if this is an update, and there is an old value to update - if (opts.update) { - update(store, val, key); + return ids; + } +}; + +/*****************/ +/* PRIVATE STUFF */ +/*****************/ + +// recursive store function +storeIt = function(store, key, opts, val, oldVal /*optional*/) { + var result, keys, oldKey; + if (key.indexOf(BSLASH_DOT) >= 0) { + keys = key.split('.'); + oldVal = store[keys[0]] ? clone(store[keys[0]]) : undefined; + oldKey = keys.shift(); + if (store[oldKey] === undefined) { + store[oldKey] = {}; } - // if not an update, just overwrite the old value - else { + return storeIt(store[oldKey], keys.join('.'), opts, val, oldVal); + } + result = oldVal ? oldVal[key] : store[key]; + // if this is an update, and there is an old value to update + if (opts.update) { + update(store, val, key); + } + // if not an update, just overwrite the old value + else { + store[key] = val; + } + return result; +}; + +// recursive update function used to overwrite values within the store without +// clobbering properties of objects +update = function(store, val, key) { + var vprop; + if (typeof val !== 'object' || val instanceof Array) { + if (store[key] && val instanceof Array) { + mergeArraysIntoSet(store[key], val); + } else { store[key] = val; } - return result; - }; - - // recursive update function used to overwrite values within the store without - // clobbering properties of objects - update = function(store, val, key) { - var vprop; - if (typeof val !== 'object' || val instanceof Array) { - if (store[key] && val instanceof Array) { - mergeArraysIntoSet(store[key], val); - } else { - store[key] = val; - } - } else { - for (vprop in val) { - if (val.hasOwnProperty(vprop)) { - if (!store[key]) { - store[key] = {}; - } - if (store[key].hasOwnProperty(vprop)) { - update(store[key], val[vprop], vprop); - } else { - store[key][vprop] = val[vprop]; - } + } else { + for (vprop in val) { + if (val.hasOwnProperty(vprop)) { + if (!store[key]) { + store[key] = {}; + } + if (store[key].hasOwnProperty(vprop)) { + update(store[key], val[vprop], vprop); + } else { + store[key][vprop] = val[vprop]; } } } - }; - - // merge two arrays without duplicate values - mergeArraysIntoSet = function(lhs, rhs) { - var i=0; - for (; i= 0) { - pulledKeys = pullOutKeys(fireOptions.value); - fireOptions.value = {}; - fireOptions.value.key = fireOptions.key + pulledKeys; - fireOptions.value.value = getValue(this._s, fireOptions.value.key.split('.')); - } else { - fireOptions.value = getValue(this._s, opts.key.split('.')); - } - } - if (fireOptions.args) { - opts.callback.apply(scope, fireOptions.args); - } else if (fireOptions.result) { - opts.callback.call(scope, fireOptions.result); + } + if (needle) { + arr.splice(needle, 1); + } +}; + +// fire an event of 'type' with included arguments to be passed to listeners functions +// WARNING: this function must be invoked as fire.call(scope, type, args) because it uses 'this'. +// The reason is so this function is not publicly exposed on JSDS instances +fire = function(type, fireOptions) { + var i, opts, scope, listeners, pulledKeys, + listeners = this._l[type] || []; + + fireOptions = fireOptions || {}; + + if (listeners.length) { + for (i=0; i= 0) { + pulledKeys = pullOutKeys(fireOptions.value); + fireOptions.value = {}; + fireOptions.value.key = fireOptions.key + pulledKeys; + fireOptions.value.value = getValue(this._s, fireOptions.value.key.split('.')); } else { - opts.callback.call(scope, type, fireOptions); + fireOptions.value = getValue(this._s, opts.key.split('.')); } } + if (fireOptions.args) { + opts.callback.apply(scope, fireOptions.args); + } else if (fireOptions.result) { + opts.callback.call(scope, fireOptions.result); + } else { + opts.callback.call(scope, fireOptions.result); + } } } - }; - - // WARNING: this function must be invoked as listenerApplies.call(scope, listener, crit) because it uses 'this'. - // The reason is so this function is not publicly exposed on JSDS instances - listenerApplies = function(listener, crit) { - console.log( - "Event %s:%s ... does %s:%s apply?", - crit.when, crit.key, listener.when, listener.key - ) - var result = false, last, sub, k, replacedKey, breakout = false; - if (listener.when && crit.when) { - if (listener.when !== crit.when) { - return false; - } + } +}; + +// WARNING: this function must be invoked as listenerApplies.call(scope, listener, crit) because it uses 'this'. +// The reason is so this function is not publicly exposed on JSDS instances +listenerApplies = function(listener, crit) { + var result = false, last, sub, k, replacedKey, breakout = false; + if (listener.when && crit.when) { + if (listener.when !== crit.when) { + return false; } - if (!listener.key || !crit) { - return true; + } + if (!listener.key || !crit) { + return true; + } + if (!crit.key || crit.key.match(toRegex('\\b' + listener.key + '\\b'))) { + return true; + } + last = crit.key.length; + while (!breakout) { + sub = crit.key.substr(0, last); + last = sub.lastIndexOf(BSLASH_DOT); + if (last < 0) { + k = sub; + breakout = true; + } else { + k = sub.substr(0, last); } - if (!crit.key || crit.key.match(toRegex(listener.key))) { - return true; + if (listener.key.indexOf('*') === 0) { + return valueMatchesKeyString(crit.value, listener.key.replace(/\*/, crit.key).substr(crit.key.length + 1)); + } else if (listener.key.indexOf('*') > 0) { + replacedKey = getCompleteKey(crit); + return toRegex(replacedKey).match(listener.key); } - last = crit.key.length; - while (!breakout) { - sub = crit.key.substr(0, last); - last = sub.lastIndexOf(BSLASH_DOT); - if (last < 0) { - k = sub; - breakout = true; - } else { - k = sub.substr(0, last); - } - if (listener.key.indexOf('*') === 0) { - return valueMatchesKeyString(crit.value, listener.key.replace(/\*/, crit.key).substr(crit.key.length + 1)); - } else if (listener.key.indexOf('*') > 0) { - replacedKey = getCompleteKey(crit); - return toRegex(replacedKey).match(listener.key); - } - return valueMatchesKeyString(crit.value, listener.key.substr(crit.key.length+1)); + return valueMatchesKeyString(crit.value, listener.key.substr(crit.key.length+1)); + } + return result; +}; + +removeListener = function(listeners, id) { + var i, l, needle; + for (i=0; i < listeners.length; i++) { + l = listeners[i]; + if (l.id && l.id === id) { + needle = i; + break; } - return result; - }; - - removeListener = function(listeners, id) { - var i, l, needle; - for (i=0; i < listeners.length; i++) { - l = listeners[i]; - if (l.id && l.id === id) { - needle = i; - break; + } + if (typeof needle !== 'undefined') { + listeners.splice(needle, 1); + } +}; + +getCompleteKey = function(o) { + var val = o.value, key = o.key; + return key + pullOutKeys(val); +}; + +pullOutKeys = function(v) { + var p, res = ''; + for (p in v) { + if (v.hasOwnProperty(p)) { + res += '.' + p; + if (typeof v[p] === 'object' && !(v[p] instanceof Array)) { + res += pullOutKeys(v[p]); } } - if (typeof needle !== 'undefined') { - listeners.splice(needle, 1); - } - }; - - getCompleteKey = function(o) { - var val = o.value, key = o.key; - return key + pullOutKeys(val); - }; - - pullOutKeys = function(v) { - var p, res = ''; - for (p in v) { - if (v.hasOwnProperty(p)) { - res += '.' + p; - if (typeof v[p] === 'object' && !(v[p] instanceof Array)) { - res += pullOutKeys(v[p]); + } + return res; +}; + +toRegex = function(s) { + return s + .replace(REGEX_DOT_G, '\\.') + .replace(REGEX_STAR_G, '\.*'); +}; + +valueMatchesKeyString = function(val, key) { + var p, i=0, keys = key.split('.'); + for (p in val) { + if (val.hasOwnProperty(p)) { + if (keys[i] === '*' || p === keys[i]) { + if ((typeof val[p] === 'object') && !(val[p] instanceof Array)) { + return valueMatchesKeyString(val[p], keys.slice(i+1).join('.')); + } else { + return true; } } } - return res; - }; - - toRegex = function(s) { - return s.replace(REGEX_DOT_G, '\\.').replace(REGEX_STAR_G, '\.*'); - }; - - valueMatchesKeyString = function(val, key) { - var p, i=0, keys = key.split('.'); - for (p in val) { - if (val.hasOwnProperty(p)) { - if (keys[i] === '*' || p === keys[i]) { - if ((typeof val[p] === 'object') && !(val[p] instanceof Array)) { - return valueMatchesKeyString(val[p], keys.slice(i+1).join('.')); - } else { - return true; - } - } - } - i++; + i++; + } + return false; +}; + +// used to copy branches within the store. Object and array friendly +clone = function(val) { + var newObj, i, prop; + if (val instanceof Array) { + newObj = []; + for (i=0; i { + + it('Create Store', () => { + let store1 = JSDS.create('store1') + expect(store1.id).to.equal('store1') + + let store2 = JSDS.create('store2') + expect(store2).to.not.equal(store1) + expect(store2.id).to.equal('store2') + JSDS.clear() + }) + + it('Get Created Store', () => { + let myStore = JSDS.create('my_store') + expect(JSDS.get('my_store')).to.equal(myStore) + JSDS.clear() + }) + + it('Creating PreExisting Store Throws Exception', () => { + JSDS.create('happy') + expect(() => { + JSDS.create('happy') + }).to.throw('Cannot overwrite existing data store "happy"!') + JSDS.clear() + }) + + it('Store Creation Without Identifier', () => { + expect(JSDS.create().id).to.not.be.undefined + JSDS.clear() + }) + +}) + +describe('when tracking different stores', () => { + + it('Get Store Count', () => { + let i=0; + for (;i<100;i++) { + JSDS.create(); + } + expect(JSDS.count()).to.equal(100) + JSDS.clear() + }) + + it('Get Store Ids', () => { + JSDS.create('a'); + JSDS.create('b'); + JSDS.create('c'); + + let result = JSDS.ids(); + + expect(result).to.deep.equal(['a', 'b', 'c']) + JSDS.clear() + }) +}) + +describe('when storing and retrieving', () => { + + it('Store String Value', () => { + setUp() + store.set('city', 'Cupertino') + let storedValue = store.get('city') + expect(storedValue).to.equal('Cupertino') + + store.set('city', 'San Jose') + storedValue = store.get('city') + expect(storedValue).to.equal('San Jose') + }) + + it('Store Number Value', () => { + setUp() + store.set('price', 5.55); + let storedValue = store.get('price') + expect(storedValue).to.equal(5.55) + + store.set('price', 3.14) + storedValue = store.get('price') + expect(storedValue).to.equal(3.14) + }) + + it('Store Object Value', () => { + setUp() + let chicken = { + name: 'Susie', eggs: 3, farm:'Hillsboro Farms' + } + store.set('chicken', chicken) + + let gotChicken = store.get('chicken') + + expect(gotChicken).to.equal(chicken) + expect(store.get('chicken.name')).to.equal('Susie') + expect(store.get('chicken', 'eggs')).to.equal(3) + }) + + it('Updating Doesnt Clobber Existing Data', () => { + setUp() + let chicken = { + name: 'Susie', eggs: 3, farm:'Hillsboro Farms' + }; + store.set('chicken', chicken); + + let newchick = { eggs: 4}; + + expect(store.get('chicken.name')).to.equal('Susie') + expect(store.get('chicken', 'eggs')).to.equal(3) + + store.set('chicken', newchick, {update: true}); + + expect(store.get('chicken', 'eggs')).to.equal(4) + expect(store.get('chicken.name')).to.equal('Susie') + expect(store.get('chicken.farm')).to.equal('Hillsboro Farms') + }) + + it('Updating Doesn\'t Clobber Existing Data with Deep Structure', () => { + setUp() + let val = { + animals: { + reptiles: { + turtles: ['Victor'] + }, + mammals: { + primates: { + humans: { + Taylors: ['Matt', 'Trinity', 'Dean', 'Romy'] + } + }, + dogs: ['Sasha', 'Ann-Marie'] + } + } + }; + + store.set('stuff', val); + + let newVal = { + animals: { + reptiles: { + lizards: ['Izzy'] + }, + mammals: { + primates: { + humans: { + Simpsons: ['Homer', 'Bart', 'Marge', 'Lisa', 'Maggie'] + } + }, + dogs: ['Scooby'] + } + } + }; + + store.set('stuff', newVal, { update: true }); + + let result = store.get('stuff.animals.reptiles.turtles'); + expect(result).to.deep.equal(['Victor']) + + result = store.get('stuff.animals.reptiles.lizards'); + expect(result).to.deep.equal(['Izzy']) + + result = store.get('stuff.animals.mammals.primates.humans'); + expect(result).to.deep.equal({ + Simpsons: ['Homer', 'Bart', 'Marge', 'Lisa', 'Maggie'], + Taylors: ['Matt', 'Trinity', 'Dean', 'Romy'] + }) + + result = store.get('stuff.animals.mammals.dogs'); + expect(result).to.deep.equal(['Sasha', 'Ann-Marie', 'Scooby']) + }) + + it('Updating Arrays Doesnt Clobber Existing Values', () => { + setUp() + store.set('obj', {arr:['one','two','three']}); + store.set('obj.arr', ['red'], {update: true}); + let res = store.get('obj.arr'); + expect(res).to.deep.equal(['one','two','three', 'red']) + + }) + + it('Updating Arrays Adds New Values To End Of Array', () => { + setUp() + store.set('arr', ['one','two','three']); + store.set('arr', ['red'], {update: true}); + let res = store.get('arr'); + expect(res).to.deep.equal(['one','two','three', 'red']) + }) + + it('Updating Arrays Doesn\'t Duplicate Array Values', () => { + setUp() + store.set('arr', ['one','two','three']); + store.set('arr', ['red', 'two'], {update: true}); + let res = store.get('arr'); + expect(res).to.deep.equal(['one','two','three','red']) + }) + + it('Store Returns Previous Value', () => { + setUp() + store.set('city', 'Cupertino'); + let prev = store.set('city', 'San Jose'); + expect(prev).to.equal('Cupertino') + }) + + it('Store Returns Undefined When Storing First Value', () => { + setUp() + let result = store.set('pig', 'Fluffy'); + expect(result).to.be.undefined + }) + + it('Store Returns Old Value When Storing Another Value', () => { + setUp() + store.set('pig', 'Fluffy'); + let result = store.set('pig', 'Orson'); + expect(result).to.equal('Fluffy') + }) + + it('Namespace Storage Combined Dots', () => { + setUp() + store.set('people', {males: ['Dean', 'Matt']}); + let result = store.get('people.males'); + expect(result).to.deep.equal(['Dean', 'Matt']) + }) + + it('Namespace Storage Separated No Dots', () => { + setUp() + store.set('people', {males: ['Dean', 'Matt']}); + let result = store.get('people', 'males'); + expect(result).to.deep.equal(['Dean', 'Matt']) + }) + + it('Namespace Storage Combined Dots Deep', () => { + setUp() + let val = { + animals: { + reptiles: { + turtles: ['Victor'] + }, + mammals: { + primates: { + humans: { + Taylors: ['Matt', 'Trinity', 'Dean', 'Romy'] + } + }, + dogs: ['Sasha', 'Ann-Marie'] + } + } + }; + + store.set('stuff', val); + + let result = store.get('stuff'); + + expect(result).to.deep.equal(val) + + result = store.get('stuff.animals.reptiles.lizards'); + expect(result).to.be.undefined + + result = store.get('stuff', 'animals', 'reptiles', 'turtles'); + expect(result).to.deep.equal(['Victor']) + + result = store.get('stuff', 'animals', 'mammals', 'primates', 'humans'); + expect(result).to.deep.equal({ + Taylors: ['Matt', 'Trinity', 'Dean', 'Romy'] + }) + }) + + it('Namespace Storage Separated No Dots Deep', () => { + setUp() + let val = { + animals: { + reptiles: { + turtles: ['Victor'] + }, + mammals: { + primates: { + humans: { + Taylors: ['Matt', 'Trinity', 'Dean', 'Romy'] + } + }, + dogs: ['Sasha', 'Ann-Marie'] + } + } + }; + + store.set('stuff', val); + + let result = store.get('stuff'); + expect(result).to.deep.equal(val) + + result = store.get('stuff.animals.reptiles.turtles'); + expect(result).to.deep.equal(['Victor']) + + result = store.get('stuff.animals.mammals.primates.humans'); + expect(result).to.deep.equal({ + Taylors: ['Matt', 'Trinity', 'Dean', 'Romy'] + }) + }) + + it('Namespace Storage COMBO Deep', () => { + setUp() + let val = { + animals: { + reptiles: { + turtles: ['Victor'] + }, + mammals: { + primates: { + humans: { + Taylors: ['Matt', 'Trinity', 'Dean', 'Romy'] + } + }, + dogs: ['Sasha', 'Ann-Marie'] + } + } + }; + + store.set('stuff', val); + + let result = store.get('stuff'); + expect(result).to.deep.equal(val) + + result = store.get('stuff.animals', 'reptiles.turtles'); + expect(result).to.deep.equal(['Victor']) + + result = store.get('stuff', 'animals.mammals.primates' , 'humans'); + expect(result).to.deep.equal({ + Taylors: ['Matt', 'Trinity', 'Dean', 'Romy'] + }) + }) + + it('Store Into Non Existant Namespace', () => { + setUp() + store.set('stuff.test', 'pygmies'); + let result = store.get('stuff', 'test'); + expect(result).to.equal('pygmies') + }) + + it('Store Returns Previous Value From Nested Namespace', () => { + setUp() + store.set('stuff.test', 'pygmies'); + let old = store.set('stuff.test', 'kidneys'); + expect(old).to.equal('pygmies') + }) + + it('Clear', () => { + setUp() + store.set('stuff', 'frogs'); + expect(store.get('stuff')).to.equal('frogs') + store.clear(); + expect(store.get('stuff')).to.be.undefined + }) + + it('Delete', () => { + setUp() + let soonDeleted = JSDS.create('removeme'); + soonDeleted.remove(); + expect(JSDS._stores['removeme']).to.be.undefined + }) + + it('Store Huge Text Blob', () => { + setUp() + let blob = '















Twitter / Home










- - - - - - - - - - - - - - - -
- - - - - - - - diff --git a/tests/jsds_perf_tests.js b/tests/jsds_perf_tests.js_ similarity index 100% rename from tests/jsds_perf_tests.js rename to tests/jsds_perf_tests.js_ diff --git a/tests/jsds_tests.html b/tests/jsds_tests.html deleted file mode 100644 index 8a373d5..0000000 --- a/tests/jsds_tests.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - -JSDS Tests - - - - - - - - - - - - - - - - - - -
- - - - - - - - diff --git a/tests/jsds_tests.js b/tests/jsds_tests.js_ similarity index 98% rename from tests/jsds_tests.js rename to tests/jsds_tests.js_ index 18f4037..1f9e1e1 100644 --- a/tests/jsds_tests.js +++ b/tests/jsds_tests.js_ @@ -1066,6 +1066,26 @@ YUI.add('jsds_tests', function(Y) { a.isTrue(called, 'cb never called'); }, + 'test after set is given raw value when value is falsey': function() { + var value = undefined; + this.s.after('set', 'fountain', function(v) { + value = v + }); + this.s.set('fountain', 0); + a.areSame(0, value, 'zero value callback was given wrong set value') + }, + + 'test after set callback is given current and previous value': function() { + let value, prev + this.s.set('my-value', 'prev') + this.s.after('set', 'my-value', function(v, p) { + value = v + prev = p + }); + this.s.set('my-value', 'current'); + a.areSame('prev', prev, 'Wrong previous value in after set callback') + }, + // 'test before set cb return value overrides call params': function() { // var called = false; // this.s.before('set', 'city', function(k, v) { diff --git a/webpack.config.js b/webpack.config.js index 3428efc..3728830 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -11,7 +11,7 @@ let version = pkg.version module.exports = { mode: 'development', entry: [ - "./src/jsds.js", + "./src/index.js" ], module: { rules: [