From 2d27ef9a59af85f2682f788b0ab6da814c75d097 Mon Sep 17 00:00:00 2001 From: rhyolight Date: Thu, 19 Apr 2018 08:26:47 -0700 Subject: [PATCH 1/7] 1.0.0: Removed after event, ensuring all listeners are called --- README.md | 17 +- docs/jsds-1.0.0.js | 21 +- package-lock.json | 3855 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +- src/index.js | 1 + src/jsds.js | 1070 ++++++------ webpack.config.js | 2 +- 7 files changed, 4414 insertions(+), 557 deletions(-) create mode 100644 src/index.js diff --git a/README.md b/README.md index 32f9a11..447985c 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,16 @@ 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/` 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/package-lock.json b/package-lock.json index 2b1c489..d81d9fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5296,6 +5296,3861 @@ "sort-keys": "2.0.0" } }, + "npm": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-5.8.0.tgz", + "integrity": "sha512-DowXzQwtSWDtbAjuWecuEiismR0VdNEYaL3VxNTYTdW6AGkYxfGk9LUZ/rt6etEyiH4IEk95HkJeGfXE5Rz9xQ==", + "requires": { + "JSONStream": "1.3.2", + "abbrev": "1.1.1", + "ansi-regex": "3.0.0", + "ansicolors": "0.3.2", + "ansistyles": "0.1.3", + "aproba": "1.2.0", + "archy": "1.0.0", + "bin-links": "1.1.0", + "bluebird": "3.5.1", + "cacache": "10.0.4", + "call-limit": "1.1.0", + "chownr": "1.0.1", + "cli-table2": "0.2.0", + "cmd-shim": "2.0.2", + "columnify": "1.5.4", + "config-chain": "1.1.11", + "debuglog": "1.0.1", + "detect-indent": "5.0.0", + "detect-newline": "2.1.0", + "dezalgo": "1.0.3", + "editor": "1.0.0", + "find-npm-prefix": "1.0.2", + "fs-vacuum": "1.2.10", + "fs-write-stream-atomic": "1.0.10", + "gentle-fs": "2.0.1", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "has-unicode": "2.0.1", + "hosted-git-info": "2.6.0", + "iferr": "0.1.5", + "imurmurhash": "0.1.4", + "inflight": "1.0.6", + "inherits": "2.0.3", + "ini": "1.3.5", + "init-package-json": "1.10.3", + "is-cidr": "1.0.0", + "json-parse-better-errors": "1.0.1", + "lazy-property": "1.0.0", + "libcipm": "1.6.0", + "libnpx": "10.0.1", + "lockfile": "1.0.3", + "lodash._baseindexof": "3.1.0", + "lodash._baseuniq": "4.6.0", + "lodash._bindcallback": "3.0.1", + "lodash._cacheindexof": "3.0.2", + "lodash._createcache": "3.1.2", + "lodash._getnative": "3.9.1", + "lodash.clonedeep": "4.5.0", + "lodash.restparam": "3.6.1", + "lodash.union": "4.6.0", + "lodash.uniq": "4.5.0", + "lodash.without": "4.4.0", + "lru-cache": "4.1.1", + "meant": "1.0.1", + "mississippi": "3.0.0", + "mkdirp": "0.5.1", + "move-concurrently": "1.0.1", + "nopt": "4.0.1", + "normalize-package-data": "2.4.0", + "npm-cache-filename": "1.0.2", + "npm-install-checks": "3.0.0", + "npm-lifecycle": "2.0.1", + "npm-package-arg": "6.0.0", + "npm-packlist": "1.1.10", + "npm-profile": "3.0.1", + "npm-registry-client": "8.5.1", + "npm-user-validate": "1.0.0", + "npmlog": "4.1.2", + "once": "1.4.0", + "opener": "1.4.3", + "osenv": "0.1.5", + "pacote": "7.6.1", + "path-is-inside": "1.0.2", + "promise-inflight": "1.0.1", + "qrcode-terminal": "0.11.0", + "query-string": "5.1.0", + "qw": "1.0.1", + "read": "1.0.7", + "read-cmd-shim": "1.0.1", + "read-installed": "4.0.3", + "read-package-json": "2.0.13", + "read-package-tree": "5.1.6", + "readable-stream": "2.3.5", + "readdir-scoped-modules": "1.0.2", + "request": "2.83.0", + "retry": "0.10.1", + "rimraf": "2.6.2", + "safe-buffer": "5.1.1", + "semver": "5.5.0", + "sha": "2.0.1", + "slide": "1.1.6", + "sorted-object": "2.0.1", + "sorted-union-stream": "2.1.3", + "ssri": "5.2.4", + "strip-ansi": "4.0.0", + "tar": "4.4.0", + "text-table": "0.2.0", + "uid-number": "0.0.6", + "umask": "1.1.0", + "unique-filename": "1.1.0", + "unpipe": "1.0.0", + "update-notifier": "2.3.0", + "uuid": "3.2.1", + "validate-npm-package-license": "3.0.1", + "validate-npm-package-name": "3.0.0", + "which": "1.3.0", + "worker-farm": "1.5.4", + "wrappy": "1.0.2", + "write-file-atomic": "2.3.0" + }, + "dependencies": { + "JSONStream": { + "version": "1.3.2", + "bundled": true, + "requires": { + "jsonparse": "1.3.1", + "through": "2.3.8" + }, + "dependencies": { + "jsonparse": { + "version": "1.3.1", + "bundled": true + }, + "through": { + "version": "2.3.8", + "bundled": true + } + } + }, + "abbrev": { + "version": "1.1.1", + "bundled": true + }, + "ansi-regex": { + "version": "3.0.0", + "bundled": true + }, + "ansicolors": { + "version": "0.3.2", + "bundled": true + }, + "ansistyles": { + "version": "0.1.3", + "bundled": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true + }, + "archy": { + "version": "1.0.0", + "bundled": true + }, + "bin-links": { + "version": "1.1.0", + "bundled": true, + "requires": { + "bluebird": "3.5.1", + "cmd-shim": "2.0.2", + "fs-write-stream-atomic": "1.0.10", + "gentle-fs": "2.0.1", + "graceful-fs": "4.1.11", + "slide": "1.1.6" + } + }, + "bluebird": { + "version": "3.5.1", + "bundled": true + }, + "cacache": { + "version": "10.0.4", + "bundled": true, + "requires": { + "bluebird": "3.5.1", + "chownr": "1.0.1", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "lru-cache": "4.1.1", + "mississippi": "2.0.0", + "mkdirp": "0.5.1", + "move-concurrently": "1.0.1", + "promise-inflight": "1.0.1", + "rimraf": "2.6.2", + "ssri": "5.2.4", + "unique-filename": "1.1.0", + "y18n": "4.0.0" + }, + "dependencies": { + "mississippi": { + "version": "2.0.0", + "bundled": true, + "requires": { + "concat-stream": "1.6.1", + "duplexify": "3.5.4", + "end-of-stream": "1.4.1", + "flush-write-stream": "1.0.2", + "from2": "2.3.0", + "parallel-transform": "1.1.0", + "pump": "2.0.1", + "pumpify": "1.4.0", + "stream-each": "1.2.2", + "through2": "2.0.3" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.1", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "typedarray": "0.0.6" + }, + "dependencies": { + "typedarray": { + "version": "0.0.6", + "bundled": true + } + } + }, + "duplexify": { + "version": "3.5.4", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "stream-shift": "1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "requires": { + "once": "1.4.0" + } + }, + "flush-write-stream": { + "version": "1.0.2", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5" + } + }, + "from2": { + "version": "2.3.0", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5" + } + }, + "parallel-transform": { + "version": "1.1.0", + "bundled": true, + "requires": { + "cyclist": "0.2.2", + "inherits": "2.0.3", + "readable-stream": "2.3.5" + }, + "dependencies": { + "cyclist": { + "version": "0.2.2", + "bundled": true + } + } + }, + "pump": { + "version": "2.0.1", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + }, + "pumpify": { + "version": "1.4.0", + "bundled": true, + "requires": { + "duplexify": "3.5.4", + "inherits": "2.0.3", + "pump": "2.0.1" + } + }, + "stream-each": { + "version": "1.2.2", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "stream-shift": "1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + }, + "through2": { + "version": "2.0.3", + "bundled": true, + "requires": { + "readable-stream": "2.3.5", + "xtend": "4.0.1" + }, + "dependencies": { + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + } + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true + } + } + }, + "call-limit": { + "version": "1.1.0", + "bundled": true + }, + "chownr": { + "version": "1.0.1", + "bundled": true + }, + "cli-table2": { + "version": "0.2.0", + "bundled": true, + "requires": { + "colors": "1.1.2", + "lodash": "3.10.1", + "string-width": "1.0.2" + }, + "dependencies": { + "colors": { + "version": "1.1.2", + "bundled": true, + "optional": true + }, + "lodash": { + "version": "3.10.1", + "bundled": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "1.0.1" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "bundled": true + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + } + } + } + } + }, + "cmd-shim": { + "version": "2.0.2", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1" + } + }, + "columnify": { + "version": "1.5.4", + "bundled": true, + "requires": { + "strip-ansi": "3.0.1", + "wcwidth": "1.0.1" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + }, + "wcwidth": { + "version": "1.0.1", + "bundled": true, + "requires": { + "defaults": "1.0.3" + }, + "dependencies": { + "defaults": { + "version": "1.0.3", + "bundled": true, + "requires": { + "clone": "1.0.2" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "bundled": true + } + } + } + } + } + } + }, + "config-chain": { + "version": "1.1.11", + "bundled": true, + "requires": { + "ini": "1.3.5", + "proto-list": "1.2.4" + }, + "dependencies": { + "proto-list": { + "version": "1.2.4", + "bundled": true + } + } + }, + "debuglog": { + "version": "1.0.1", + "bundled": true + }, + "detect-indent": { + "version": "5.0.0", + "bundled": true + }, + "detect-newline": { + "version": "2.1.0", + "bundled": true + }, + "dezalgo": { + "version": "1.0.3", + "bundled": true, + "requires": { + "asap": "2.0.5", + "wrappy": "1.0.2" + }, + "dependencies": { + "asap": { + "version": "2.0.5", + "bundled": true + } + } + }, + "editor": { + "version": "1.0.0", + "bundled": true + }, + "find-npm-prefix": { + "version": "1.0.2", + "bundled": true + }, + "fs-vacuum": { + "version": "1.2.10", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11", + "path-is-inside": "1.0.2", + "rimraf": "2.6.2" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11", + "iferr": "0.1.5", + "imurmurhash": "0.1.4", + "readable-stream": "2.3.5" + } + }, + "gentle-fs": { + "version": "2.0.1", + "bundled": true, + "requires": { + "aproba": "1.2.0", + "fs-vacuum": "1.2.10", + "graceful-fs": "4.1.11", + "iferr": "0.1.5", + "mkdirp": "0.5.1", + "path-is-inside": "1.0.2", + "read-cmd-shim": "1.0.1", + "slide": "1.1.6" + } + }, + "glob": { + "version": "7.1.2", + "bundled": 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" + }, + "dependencies": { + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "1.1.8" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "bundled": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + } + } + } + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true + }, + "hosted-git-info": { + "version": "2.6.0", + "bundled": true + }, + "iferr": { + "version": "0.1.5", + "bundled": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true + }, + "ini": { + "version": "1.3.5", + "bundled": true + }, + "init-package-json": { + "version": "1.10.3", + "bundled": true, + "requires": { + "glob": "7.1.2", + "npm-package-arg": "6.0.0", + "promzard": "0.3.0", + "read": "1.0.7", + "read-package-json": "2.0.13", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.1", + "validate-npm-package-name": "3.0.0" + }, + "dependencies": { + "promzard": { + "version": "0.3.0", + "bundled": true, + "requires": { + "read": "1.0.7" + } + } + } + }, + "is-cidr": { + "version": "1.0.0", + "bundled": true, + "requires": { + "cidr-regex": "1.0.6" + }, + "dependencies": { + "cidr-regex": { + "version": "1.0.6", + "bundled": true + } + } + }, + "json-parse-better-errors": { + "version": "1.0.1", + "bundled": true + }, + "lazy-property": { + "version": "1.0.0", + "bundled": true + }, + "libcipm": { + "version": "1.6.0", + "bundled": true, + "requires": { + "bin-links": "1.1.0", + "bluebird": "3.5.1", + "find-npm-prefix": "1.0.2", + "graceful-fs": "4.1.11", + "lock-verify": "2.0.0", + "npm-lifecycle": "2.0.1", + "npm-logical-tree": "1.2.1", + "npm-package-arg": "6.0.0", + "pacote": "7.6.1", + "protoduck": "5.0.0", + "read-package-json": "2.0.13", + "rimraf": "2.6.2", + "worker-farm": "1.5.4" + }, + "dependencies": { + "lock-verify": { + "version": "2.0.0", + "bundled": true, + "requires": { + "npm-package-arg": "5.1.2", + "semver": "5.5.0" + }, + "dependencies": { + "npm-package-arg": { + "version": "5.1.2", + "bundled": true, + "requires": { + "hosted-git-info": "2.6.0", + "osenv": "0.1.5", + "semver": "5.5.0", + "validate-npm-package-name": "3.0.0" + } + } + } + }, + "npm-logical-tree": { + "version": "1.2.1", + "bundled": true + }, + "protoduck": { + "version": "5.0.0", + "bundled": true, + "requires": { + "genfun": "4.0.1" + }, + "dependencies": { + "genfun": { + "version": "4.0.1", + "bundled": true + } + } + }, + "worker-farm": { + "version": "1.5.4", + "bundled": true, + "requires": { + "errno": "0.1.7", + "xtend": "4.0.1" + }, + "dependencies": { + "errno": { + "version": "0.1.7", + "bundled": true, + "requires": { + "prr": "1.0.1" + }, + "dependencies": { + "prr": { + "version": "1.0.1", + "bundled": true + } + } + }, + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + } + } + }, + "libnpx": { + "version": "10.0.1", + "bundled": true, + "requires": { + "dotenv": "5.0.1", + "npm-package-arg": "6.0.0", + "rimraf": "2.6.2", + "safe-buffer": "5.1.1", + "update-notifier": "2.3.0", + "which": "1.3.0", + "y18n": "4.0.0", + "yargs": "11.0.0" + }, + "dependencies": { + "dotenv": { + "version": "5.0.1", + "bundled": true + }, + "y18n": { + "version": "4.0.0", + "bundled": true + }, + "yargs": { + "version": "11.0.0", + "bundled": true, + "requires": { + "cliui": "4.0.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": { + "cliui": { + "version": "4.0.0", + "bundled": true, + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "1.0.1" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "bundled": true + } + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + } + } + } + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true + }, + "find-up": { + "version": "2.1.0", + "bundled": true, + "requires": { + "locate-path": "2.0.0" + }, + "dependencies": { + "locate-path": { + "version": "2.0.0", + "bundled": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "p-locate": { + "version": "2.0.0", + "bundled": true, + "requires": { + "p-limit": "1.2.0" + }, + "dependencies": { + "p-limit": { + "version": "1.2.0", + "bundled": true, + "requires": { + "p-try": "1.0.0" + }, + "dependencies": { + "p-try": { + "version": "1.0.0", + "bundled": true + } + } + } + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true + } + } + } + } + }, + "get-caller-file": { + "version": "1.0.2", + "bundled": true + }, + "os-locale": { + "version": "2.1.0", + "bundled": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + }, + "dependencies": { + "execa": { + "version": "0.7.0", + "bundled": 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, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + }, + "dependencies": { + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "requires": { + "shebang-regex": "1.0.0" + }, + "dependencies": { + "shebang-regex": { + "version": "1.0.0", + "bundled": true + } + } + } + } + }, + "get-stream": { + "version": "3.0.0", + "bundled": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "requires": { + "path-key": "2.0.1" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "bundled": true + } + } + }, + "p-finally": { + "version": "1.0.0", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true + } + } + }, + "lcid": { + "version": "1.0.0", + "bundled": true, + "requires": { + "invert-kv": "1.0.0" + }, + "dependencies": { + "invert-kv": { + "version": "1.0.0", + "bundled": true + } + } + }, + "mem": { + "version": "1.1.0", + "bundled": true, + "requires": { + "mimic-fn": "1.2.0" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "bundled": true + } + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true + } + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true + }, + "y18n": { + "version": "3.2.1", + "bundled": true + }, + "yargs-parser": { + "version": "9.0.2", + "bundled": true, + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "bundled": true + } + } + } + } + } + } + }, + "lockfile": { + "version": "1.0.3", + "bundled": true + }, + "lodash._baseindexof": { + "version": "3.1.0", + "bundled": true + }, + "lodash._baseuniq": { + "version": "4.6.0", + "bundled": true, + "requires": { + "lodash._createset": "4.0.3", + "lodash._root": "3.0.1" + }, + "dependencies": { + "lodash._createset": { + "version": "4.0.3", + "bundled": true + }, + "lodash._root": { + "version": "3.0.1", + "bundled": true + } + } + }, + "lodash._bindcallback": { + "version": "3.0.1", + "bundled": true + }, + "lodash._cacheindexof": { + "version": "3.0.2", + "bundled": true + }, + "lodash._createcache": { + "version": "3.1.2", + "bundled": true, + "requires": { + "lodash._getnative": "3.9.1" + } + }, + "lodash._getnative": { + "version": "3.9.1", + "bundled": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "bundled": true + }, + "lodash.restparam": { + "version": "3.6.1", + "bundled": true + }, + "lodash.union": { + "version": "4.6.0", + "bundled": true + }, + "lodash.uniq": { + "version": "4.5.0", + "bundled": true + }, + "lodash.without": { + "version": "4.4.0", + "bundled": true + }, + "lru-cache": { + "version": "4.1.1", + "bundled": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + }, + "dependencies": { + "pseudomap": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true + } + } + }, + "meant": { + "version": "1.0.1", + "bundled": true + }, + "mississippi": { + "version": "3.0.0", + "bundled": true, + "requires": { + "concat-stream": "1.6.1", + "duplexify": "3.5.4", + "end-of-stream": "1.4.1", + "flush-write-stream": "1.0.2", + "from2": "2.3.0", + "parallel-transform": "1.1.0", + "pump": "3.0.0", + "pumpify": "1.4.0", + "stream-each": "1.2.2", + "through2": "2.0.3" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.1", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "typedarray": "0.0.6" + }, + "dependencies": { + "typedarray": { + "version": "0.0.6", + "bundled": true + } + } + }, + "duplexify": { + "version": "3.5.4", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "stream-shift": "1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "requires": { + "once": "1.4.0" + } + }, + "flush-write-stream": { + "version": "1.0.2", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5" + } + }, + "from2": { + "version": "2.3.0", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5" + } + }, + "parallel-transform": { + "version": "1.1.0", + "bundled": true, + "requires": { + "cyclist": "0.2.2", + "inherits": "2.0.3", + "readable-stream": "2.3.5" + }, + "dependencies": { + "cyclist": { + "version": "0.2.2", + "bundled": true + } + } + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + }, + "pumpify": { + "version": "1.4.0", + "bundled": true, + "requires": { + "duplexify": "3.5.4", + "inherits": "2.0.3", + "pump": "2.0.1" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + } + } + }, + "stream-each": { + "version": "1.2.2", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "stream-shift": "1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + }, + "through2": { + "version": "2.0.3", + "bundled": true, + "requires": { + "readable-stream": "2.3.5", + "xtend": "4.0.1" + }, + "dependencies": { + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true + } + } + }, + "move-concurrently": { + "version": "1.0.1", + "bundled": true, + "requires": { + "aproba": "1.2.0", + "copy-concurrently": "1.0.5", + "fs-write-stream-atomic": "1.0.10", + "mkdirp": "0.5.1", + "rimraf": "2.6.2", + "run-queue": "1.0.3" + }, + "dependencies": { + "copy-concurrently": { + "version": "1.0.5", + "bundled": true, + "requires": { + "aproba": "1.2.0", + "fs-write-stream-atomic": "1.0.10", + "iferr": "0.1.5", + "mkdirp": "0.5.1", + "rimraf": "2.6.2", + "run-queue": "1.0.3" + } + }, + "run-queue": { + "version": "1.0.3", + "bundled": true, + "requires": { + "aproba": "1.2.0" + } + } + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "requires": { + "abbrev": "1.1.1", + "osenv": "0.1.5" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "requires": { + "hosted-git-info": "2.6.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.1" + }, + "dependencies": { + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "requires": { + "builtin-modules": "1.1.1" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.1", + "bundled": true + } + } + } + } + }, + "npm-cache-filename": { + "version": "1.0.2", + "bundled": true + }, + "npm-install-checks": { + "version": "3.0.0", + "bundled": true, + "requires": { + "semver": "5.5.0" + } + }, + "npm-lifecycle": { + "version": "2.0.1", + "bundled": true, + "requires": { + "byline": "5.0.0", + "graceful-fs": "4.1.11", + "node-gyp": "3.6.2", + "resolve-from": "4.0.0", + "slide": "1.1.6", + "uid-number": "0.0.6", + "umask": "1.1.0", + "which": "1.3.0" + }, + "dependencies": { + "byline": { + "version": "5.0.0", + "bundled": true + }, + "node-gyp": { + "version": "3.6.2", + "bundled": true, + "requires": { + "fstream": "1.0.11", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "npmlog": "4.1.2", + "osenv": "0.1.5", + "request": "2.83.0", + "rimraf": "2.6.2", + "semver": "5.3.0", + "tar": "2.2.1", + "which": "1.3.0" + }, + "dependencies": { + "fstream": { + "version": "1.0.11", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "1.1.11" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + } + } + } + } + }, + "nopt": { + "version": "3.0.6", + "bundled": true, + "requires": { + "abbrev": "1.1.1" + } + }, + "semver": { + "version": "5.3.0", + "bundled": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + }, + "dependencies": { + "block-stream": { + "version": "0.0.9", + "bundled": true, + "requires": { + "inherits": "2.0.3" + } + } + } + } + } + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true + } + } + }, + "npm-package-arg": { + "version": "6.0.0", + "bundled": true, + "requires": { + "hosted-git-info": "2.6.0", + "osenv": "0.1.5", + "semver": "5.5.0", + "validate-npm-package-name": "3.0.0" + } + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "requires": { + "ignore-walk": "3.0.1", + "npm-bundled": "1.0.3" + }, + "dependencies": { + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "requires": { + "minimatch": "3.0.4" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "1.1.8" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "bundled": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + } + } + } + } + } + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true + } + } + }, + "npm-profile": { + "version": "3.0.1", + "bundled": true, + "requires": { + "aproba": "1.2.0", + "make-fetch-happen": "2.6.0" + }, + "dependencies": { + "make-fetch-happen": { + "version": "2.6.0", + "bundled": true, + "requires": { + "agentkeepalive": "3.3.0", + "cacache": "10.0.4", + "http-cache-semantics": "3.8.1", + "http-proxy-agent": "2.0.0", + "https-proxy-agent": "2.1.1", + "lru-cache": "4.1.1", + "mississippi": "1.3.1", + "node-fetch-npm": "2.0.2", + "promise-retry": "1.1.1", + "socks-proxy-agent": "3.0.1", + "ssri": "5.2.4" + }, + "dependencies": { + "agentkeepalive": { + "version": "3.3.0", + "bundled": true, + "requires": { + "humanize-ms": "1.2.1" + }, + "dependencies": { + "humanize-ms": { + "version": "1.2.1", + "bundled": true, + "requires": { + "ms": "2.1.1" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "bundled": true + } + } + } + } + }, + "http-cache-semantics": { + "version": "3.8.1", + "bundled": true + }, + "http-proxy-agent": { + "version": "2.0.0", + "bundled": true, + "requires": { + "agent-base": "4.2.0", + "debug": "2.6.9" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "bundled": true, + "requires": { + "es6-promisify": "5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "4.2.4" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.4", + "bundled": true + } + } + } + } + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true + } + } + } + } + }, + "https-proxy-agent": { + "version": "2.1.1", + "bundled": true, + "requires": { + "agent-base": "4.2.0", + "debug": "3.1.0" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "bundled": true, + "requires": { + "es6-promisify": "5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "4.2.4" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.4", + "bundled": true + } + } + } + } + }, + "debug": { + "version": "3.1.0", + "bundled": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true + } + } + } + } + }, + "mississippi": { + "version": "1.3.1", + "bundled": true, + "requires": { + "concat-stream": "1.6.0", + "duplexify": "3.5.3", + "end-of-stream": "1.4.1", + "flush-write-stream": "1.0.2", + "from2": "2.3.0", + "parallel-transform": "1.1.0", + "pump": "1.0.3", + "pumpify": "1.4.0", + "stream-each": "1.2.2", + "through2": "2.0.3" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "typedarray": "0.0.6" + }, + "dependencies": { + "typedarray": { + "version": "0.0.6", + "bundled": true + } + } + }, + "duplexify": { + "version": "3.5.3", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "stream-shift": "1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "requires": { + "once": "1.4.0" + } + }, + "flush-write-stream": { + "version": "1.0.2", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5" + } + }, + "from2": { + "version": "2.3.0", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5" + } + }, + "parallel-transform": { + "version": "1.1.0", + "bundled": true, + "requires": { + "cyclist": "0.2.2", + "inherits": "2.0.3", + "readable-stream": "2.3.5" + }, + "dependencies": { + "cyclist": { + "version": "0.2.2", + "bundled": true + } + } + }, + "pump": { + "version": "1.0.3", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + }, + "pumpify": { + "version": "1.4.0", + "bundled": true, + "requires": { + "duplexify": "3.5.3", + "inherits": "2.0.3", + "pump": "2.0.1" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + } + } + }, + "stream-each": { + "version": "1.2.2", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "stream-shift": "1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + }, + "through2": { + "version": "2.0.3", + "bundled": true, + "requires": { + "readable-stream": "2.3.5", + "xtend": "4.0.1" + }, + "dependencies": { + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + } + } + }, + "node-fetch-npm": { + "version": "2.0.2", + "bundled": true, + "requires": { + "encoding": "0.1.12", + "json-parse-better-errors": "1.0.1", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "encoding": { + "version": "0.1.12", + "bundled": true, + "requires": { + "iconv-lite": "0.4.19" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.19", + "bundled": true + } + } + }, + "json-parse-better-errors": { + "version": "1.0.1", + "bundled": true + } + } + }, + "promise-retry": { + "version": "1.1.1", + "bundled": true, + "requires": { + "err-code": "1.1.2", + "retry": "0.10.1" + }, + "dependencies": { + "err-code": { + "version": "1.1.2", + "bundled": true + } + } + }, + "socks-proxy-agent": { + "version": "3.0.1", + "bundled": true, + "requires": { + "agent-base": "4.2.0", + "socks": "1.1.10" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "bundled": true, + "requires": { + "es6-promisify": "5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "4.2.4" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.4", + "bundled": true + } + } + } + } + }, + "socks": { + "version": "1.1.10", + "bundled": true, + "requires": { + "ip": "1.1.5", + "smart-buffer": "1.1.15" + }, + "dependencies": { + "ip": { + "version": "1.1.5", + "bundled": true + }, + "smart-buffer": { + "version": "1.1.15", + "bundled": true + } + } + } + } + } + } + } + } + }, + "npm-registry-client": { + "version": "8.5.1", + "bundled": true, + "requires": { + "concat-stream": "1.6.1", + "graceful-fs": "4.1.11", + "normalize-package-data": "2.4.0", + "npm-package-arg": "6.0.0", + "npmlog": "4.1.2", + "once": "1.4.0", + "request": "2.83.0", + "retry": "0.10.1", + "safe-buffer": "5.1.1", + "semver": "5.5.0", + "slide": "1.1.6", + "ssri": "5.2.4" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.1", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "typedarray": "0.0.6" + }, + "dependencies": { + "typedarray": { + "version": "0.0.6", + "bundled": true + } + } + } + } + }, + "npm-user-validate": { + "version": "1.0.0", + "bundled": true + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + }, + "dependencies": { + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.5" + }, + "dependencies": { + "delegates": { + "version": "1.0.0", + "bundled": true + } + } + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "1.0.1" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "bundled": true + } + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "requires": { + "string-width": "1.0.2" + } + } + } + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true + } + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "opener": { + "version": "1.4.3", + "bundled": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.2", + "bundled": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true + } + } + }, + "pacote": { + "version": "7.6.1", + "bundled": true, + "requires": { + "bluebird": "3.5.1", + "cacache": "10.0.4", + "get-stream": "3.0.0", + "glob": "7.1.2", + "lru-cache": "4.1.1", + "make-fetch-happen": "2.6.0", + "minimatch": "3.0.4", + "mississippi": "3.0.0", + "mkdirp": "0.5.1", + "normalize-package-data": "2.4.0", + "npm-package-arg": "6.0.0", + "npm-packlist": "1.1.10", + "npm-pick-manifest": "2.1.0", + "osenv": "0.1.5", + "promise-inflight": "1.0.1", + "promise-retry": "1.1.1", + "protoduck": "5.0.0", + "rimraf": "2.6.2", + "safe-buffer": "5.1.1", + "semver": "5.5.0", + "ssri": "5.2.4", + "tar": "4.4.0", + "unique-filename": "1.1.0", + "which": "1.3.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "bundled": true + }, + "make-fetch-happen": { + "version": "2.6.0", + "bundled": true, + "requires": { + "agentkeepalive": "3.4.0", + "cacache": "10.0.4", + "http-cache-semantics": "3.8.1", + "http-proxy-agent": "2.1.0", + "https-proxy-agent": "2.2.0", + "lru-cache": "4.1.1", + "mississippi": "1.3.1", + "node-fetch-npm": "2.0.2", + "promise-retry": "1.1.1", + "socks-proxy-agent": "3.0.1", + "ssri": "5.2.4" + }, + "dependencies": { + "agentkeepalive": { + "version": "3.4.0", + "bundled": true, + "requires": { + "humanize-ms": "1.2.1" + }, + "dependencies": { + "humanize-ms": { + "version": "1.2.1", + "bundled": true, + "requires": { + "ms": "2.1.1" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "bundled": true + } + } + } + } + }, + "http-cache-semantics": { + "version": "3.8.1", + "bundled": true + }, + "http-proxy-agent": { + "version": "2.1.0", + "bundled": true, + "requires": { + "agent-base": "4.2.0", + "debug": "3.1.0" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "bundled": true, + "requires": { + "es6-promisify": "5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "4.2.4" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.4", + "bundled": true + } + } + } + } + }, + "debug": { + "version": "3.1.0", + "bundled": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true + } + } + } + } + }, + "https-proxy-agent": { + "version": "2.2.0", + "bundled": true, + "requires": { + "agent-base": "4.2.0", + "debug": "3.1.0" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "bundled": true, + "requires": { + "es6-promisify": "5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "4.2.4" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.4", + "bundled": true + } + } + } + } + }, + "debug": { + "version": "3.1.0", + "bundled": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true + } + } + } + } + }, + "mississippi": { + "version": "1.3.1", + "bundled": true, + "requires": { + "concat-stream": "1.6.1", + "duplexify": "3.5.4", + "end-of-stream": "1.4.1", + "flush-write-stream": "1.0.2", + "from2": "2.3.0", + "parallel-transform": "1.1.0", + "pump": "1.0.3", + "pumpify": "1.4.0", + "stream-each": "1.2.2", + "through2": "2.0.3" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.1", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "typedarray": "0.0.6" + }, + "dependencies": { + "typedarray": { + "version": "0.0.6", + "bundled": true + } + } + }, + "duplexify": { + "version": "3.5.4", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "stream-shift": "1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "requires": { + "once": "1.4.0" + } + }, + "flush-write-stream": { + "version": "1.0.2", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5" + } + }, + "from2": { + "version": "2.3.0", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5" + } + }, + "parallel-transform": { + "version": "1.1.0", + "bundled": true, + "requires": { + "cyclist": "0.2.2", + "inherits": "2.0.3", + "readable-stream": "2.3.5" + }, + "dependencies": { + "cyclist": { + "version": "0.2.2", + "bundled": true + } + } + }, + "pump": { + "version": "1.0.3", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + }, + "pumpify": { + "version": "1.4.0", + "bundled": true, + "requires": { + "duplexify": "3.5.4", + "inherits": "2.0.3", + "pump": "2.0.1" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + } + } + }, + "stream-each": { + "version": "1.2.2", + "bundled": true, + "requires": { + "end-of-stream": "1.4.1", + "stream-shift": "1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + }, + "through2": { + "version": "2.0.3", + "bundled": true, + "requires": { + "readable-stream": "2.3.5", + "xtend": "4.0.1" + }, + "dependencies": { + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + } + } + }, + "node-fetch-npm": { + "version": "2.0.2", + "bundled": true, + "requires": { + "encoding": "0.1.12", + "json-parse-better-errors": "1.0.1", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "encoding": { + "version": "0.1.12", + "bundled": true, + "requires": { + "iconv-lite": "0.4.19" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.19", + "bundled": true + } + } + }, + "json-parse-better-errors": { + "version": "1.0.1", + "bundled": true + } + } + }, + "socks-proxy-agent": { + "version": "3.0.1", + "bundled": true, + "requires": { + "agent-base": "4.2.0", + "socks": "1.1.10" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "bundled": true, + "requires": { + "es6-promisify": "5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "4.2.4" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.4", + "bundled": true + } + } + } + } + }, + "socks": { + "version": "1.1.10", + "bundled": true, + "requires": { + "ip": "1.1.5", + "smart-buffer": "1.1.15" + }, + "dependencies": { + "ip": { + "version": "1.1.5", + "bundled": true + }, + "smart-buffer": { + "version": "1.1.15", + "bundled": true + } + } + } + } + } + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "1.1.11" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + } + } + } + } + }, + "npm-pick-manifest": { + "version": "2.1.0", + "bundled": true, + "requires": { + "npm-package-arg": "6.0.0", + "semver": "5.5.0" + } + }, + "promise-retry": { + "version": "1.1.1", + "bundled": true, + "requires": { + "err-code": "1.1.2", + "retry": "0.10.1" + }, + "dependencies": { + "err-code": { + "version": "1.1.2", + "bundled": true + } + } + }, + "protoduck": { + "version": "5.0.0", + "bundled": true, + "requires": { + "genfun": "4.0.1" + }, + "dependencies": { + "genfun": { + "version": "4.0.1", + "bundled": true + } + } + } + } + }, + "path-is-inside": { + "version": "1.0.2", + "bundled": true + }, + "promise-inflight": { + "version": "1.0.1", + "bundled": true + }, + "qrcode-terminal": { + "version": "0.11.0", + "bundled": true + }, + "query-string": { + "version": "5.1.0", + "bundled": true, + "requires": { + "decode-uri-component": "0.2.0", + "object-assign": "4.1.1", + "strict-uri-encode": "1.1.0" + }, + "dependencies": { + "decode-uri-component": { + "version": "0.2.0", + "bundled": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "strict-uri-encode": { + "version": "1.1.0", + "bundled": true + } + } + }, + "qw": { + "version": "1.0.1", + "bundled": true + }, + "read": { + "version": "1.0.7", + "bundled": true, + "requires": { + "mute-stream": "0.0.7" + }, + "dependencies": { + "mute-stream": { + "version": "0.0.7", + "bundled": true + } + } + }, + "read-cmd-shim": { + "version": "1.0.1", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "read-installed": { + "version": "4.0.3", + "bundled": true, + "requires": { + "debuglog": "1.0.1", + "graceful-fs": "4.1.11", + "read-package-json": "2.0.13", + "readdir-scoped-modules": "1.0.2", + "semver": "5.5.0", + "slide": "1.1.6", + "util-extend": "1.0.3" + }, + "dependencies": { + "util-extend": { + "version": "1.0.3", + "bundled": true + } + } + }, + "read-package-json": { + "version": "2.0.13", + "bundled": true, + "requires": { + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "json-parse-better-errors": "1.0.1", + "normalize-package-data": "2.4.0", + "slash": "1.0.0" + }, + "dependencies": { + "json-parse-better-errors": { + "version": "1.0.1", + "bundled": true + }, + "slash": { + "version": "1.0.0", + "bundled": true + } + } + }, + "read-package-tree": { + "version": "5.1.6", + "bundled": true, + "requires": { + "debuglog": "1.0.1", + "dezalgo": "1.0.3", + "once": "1.4.0", + "read-package-json": "2.0.13", + "readdir-scoped-modules": "1.0.2" + } + }, + "readable-stream": { + "version": "2.3.5", + "bundled": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true + }, + "string_decoder": { + "version": "1.0.3", + "bundled": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + } + } + }, + "readdir-scoped-modules": { + "version": "1.0.2", + "bundled": true, + "requires": { + "debuglog": "1.0.1", + "dezalgo": "1.0.3", + "graceful-fs": "4.1.11", + "once": "1.4.0" + } + }, + "request": { + "version": "2.83.0", + "bundled": true, + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" + }, + "dependencies": { + "aws-sign2": { + "version": "0.7.0", + "bundled": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "requires": { + "delayed-stream": "1.0.0" + }, + "dependencies": { + "delayed-stream": { + "version": "1.0.0", + "bundled": true + } + } + }, + "extend": { + "version": "3.0.1", + "bundled": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true + }, + "form-data": { + "version": "2.3.1", + "bundled": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + }, + "dependencies": { + "asynckit": { + "version": "0.4.0", + "bundled": true + } + } + }, + "har-validator": { + "version": "5.0.3", + "bundled": true, + "requires": { + "ajv": "5.2.3", + "har-schema": "2.0.0" + }, + "dependencies": { + "ajv": { + "version": "5.2.3", + "bundled": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "json-schema-traverse": "0.3.1", + "json-stable-stringify": "1.0.1" + }, + "dependencies": { + "co": { + "version": "4.6.0", + "bundled": true + }, + "fast-deep-equal": { + "version": "1.0.0", + "bundled": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "bundled": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "requires": { + "jsonify": "0.0.0" + }, + "dependencies": { + "jsonify": { + "version": "0.0.0", + "bundled": true + } + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "bundled": true + } + } + }, + "hawk": { + "version": "6.0.2", + "bundled": true, + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.0.2" + }, + "dependencies": { + "boom": { + "version": "4.3.1", + "bundled": true, + "requires": { + "hoek": "4.2.0" + } + }, + "cryptiles": { + "version": "3.1.2", + "bundled": true, + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "bundled": true, + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "hoek": { + "version": "4.2.0", + "bundled": true + }, + "sntp": { + "version": "2.0.2", + "bundled": true, + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "http-signature": { + "version": "1.2.0", + "bundled": true, + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true + }, + "jsprim": { + "version": "1.4.1", + "bundled": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + }, + "dependencies": { + "extsprintf": { + "version": "1.3.0", + "bundled": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true + }, + "verror": { + "version": "1.10.0", + "bundled": true, + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "bundled": true + } + } + } + } + }, + "sshpk": { + "version": "1.13.1", + "bundled": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "asn1": { + "version": "0.2.3", + "bundled": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "requires": { + "assert-plus": "1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "requires": { + "assert-plus": "1.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "optional": true + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "optional": true + } + } + } + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true + }, + "mime-types": { + "version": "2.1.17", + "bundled": true, + "requires": { + "mime-db": "1.30.0" + }, + "dependencies": { + "mime-db": { + "version": "1.30.0", + "bundled": true + } + } + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true + }, + "performance-now": { + "version": "2.1.0", + "bundled": true + }, + "qs": { + "version": "6.5.1", + "bundled": true + }, + "stringstream": { + "version": "0.0.5", + "bundled": true + }, + "tough-cookie": { + "version": "2.3.3", + "bundled": true, + "requires": { + "punycode": "1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "bundled": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "retry": { + "version": "0.10.1", + "bundled": true + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true + }, + "semver": { + "version": "5.5.0", + "bundled": true + }, + "sha": { + "version": "2.0.1", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11", + "readable-stream": "2.3.5" + } + }, + "slide": { + "version": "1.1.6", + "bundled": true + }, + "sorted-object": { + "version": "2.0.1", + "bundled": true + }, + "sorted-union-stream": { + "version": "2.1.3", + "bundled": true, + "requires": { + "from2": "1.3.0", + "stream-iterate": "1.2.0" + }, + "dependencies": { + "from2": { + "version": "1.3.0", + "bundled": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "bundled": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "isarray": { + "version": "0.0.1", + "bundled": true + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true + } + } + } + } + }, + "stream-iterate": { + "version": "1.2.0", + "bundled": true, + "requires": { + "readable-stream": "2.3.5", + "stream-shift": "1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + } + } + }, + "ssri": { + "version": "5.2.4", + "bundled": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "requires": { + "ansi-regex": "3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true + } + } + }, + "tar": { + "version": "4.4.0", + "bundled": true, + "requires": { + "chownr": "1.0.1", + "fs-minipass": "1.2.5", + "minipass": "2.2.1", + "minizlib": "1.1.0", + "mkdirp": "0.5.1", + "yallist": "3.0.2" + }, + "dependencies": { + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "requires": { + "minipass": "2.2.1" + } + }, + "minipass": { + "version": "2.2.1", + "bundled": true, + "requires": { + "yallist": "3.0.2" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "requires": { + "minipass": "2.2.1" + } + }, + "yallist": { + "version": "3.0.2", + "bundled": true + } + } + }, + "text-table": { + "version": "0.2.0", + "bundled": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true + }, + "umask": { + "version": "1.1.0", + "bundled": true + }, + "unique-filename": { + "version": "1.1.0", + "bundled": true, + "requires": { + "unique-slug": "2.0.0" + }, + "dependencies": { + "unique-slug": { + "version": "2.0.0", + "bundled": true, + "requires": { + "imurmurhash": "0.1.4" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "bundled": true + }, + "update-notifier": { + "version": "2.3.0", + "bundled": true, + "requires": { + "boxen": "1.2.1", + "chalk": "2.1.0", + "configstore": "3.1.1", + "import-lazy": "2.1.0", + "is-installed-globally": "0.1.0", + "is-npm": "1.0.0", + "latest-version": "3.1.0", + "semver-diff": "2.1.0", + "xdg-basedir": "3.0.0" + }, + "dependencies": { + "boxen": { + "version": "1.2.1", + "bundled": true, + "requires": { + "ansi-align": "2.0.0", + "camelcase": "4.1.0", + "chalk": "2.1.0", + "cli-boxes": "1.0.0", + "string-width": "2.1.1", + "term-size": "1.2.0", + "widest-line": "1.0.0" + }, + "dependencies": { + "ansi-align": { + "version": "2.0.0", + "bundled": true, + "requires": { + "string-width": "2.1.1" + } + }, + "camelcase": { + "version": "4.1.0", + "bundled": true + }, + "cli-boxes": { + "version": "1.0.0", + "bundled": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true + } + } + }, + "term-size": { + "version": "1.2.0", + "bundled": true, + "requires": { + "execa": "0.7.0" + }, + "dependencies": { + "execa": { + "version": "0.7.0", + "bundled": 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, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + }, + "dependencies": { + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "requires": { + "shebang-regex": "1.0.0" + }, + "dependencies": { + "shebang-regex": { + "version": "1.0.0", + "bundled": true + } + } + } + } + }, + "get-stream": { + "version": "3.0.0", + "bundled": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "requires": { + "path-key": "2.0.1" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "bundled": true + } + } + }, + "p-finally": { + "version": "1.0.0", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true + } + } + } + } + }, + "widest-line": { + "version": "1.0.0", + "bundled": true, + "requires": { + "string-width": "1.0.2" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "1.0.1" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "bundled": true + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + } + } + } + } + } + } + }, + "chalk": { + "version": "2.1.0", + "bundled": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "bundled": true, + "requires": { + "color-convert": "1.9.0" + }, + "dependencies": { + "color-convert": { + "version": "1.9.0", + "bundled": true, + "requires": { + "color-name": "1.1.3" + }, + "dependencies": { + "color-name": { + "version": "1.1.3", + "bundled": true + } + } + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true + }, + "supports-color": { + "version": "4.4.0", + "bundled": true, + "requires": { + "has-flag": "2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "bundled": true + } + } + } + } + }, + "configstore": { + "version": "3.1.1", + "bundled": true, + "requires": { + "dot-prop": "4.2.0", + "graceful-fs": "4.1.11", + "make-dir": "1.0.0", + "unique-string": "1.0.0", + "write-file-atomic": "2.3.0", + "xdg-basedir": "3.0.0" + }, + "dependencies": { + "dot-prop": { + "version": "4.2.0", + "bundled": true, + "requires": { + "is-obj": "1.0.1" + }, + "dependencies": { + "is-obj": { + "version": "1.0.1", + "bundled": true + } + } + }, + "make-dir": { + "version": "1.0.0", + "bundled": true, + "requires": { + "pify": "2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "bundled": true + } + } + }, + "unique-string": { + "version": "1.0.0", + "bundled": true, + "requires": { + "crypto-random-string": "1.0.0" + }, + "dependencies": { + "crypto-random-string": { + "version": "1.0.0", + "bundled": true + } + } + } + } + }, + "import-lazy": { + "version": "2.1.0", + "bundled": true + }, + "is-installed-globally": { + "version": "0.1.0", + "bundled": true, + "requires": { + "global-dirs": "0.1.0", + "is-path-inside": "1.0.0" + }, + "dependencies": { + "global-dirs": { + "version": "0.1.0", + "bundled": true, + "requires": { + "ini": "1.3.5" + } + }, + "is-path-inside": { + "version": "1.0.0", + "bundled": true, + "requires": { + "path-is-inside": "1.0.2" + } + } + } + }, + "is-npm": { + "version": "1.0.0", + "bundled": true + }, + "latest-version": { + "version": "3.1.0", + "bundled": true, + "requires": { + "package-json": "4.0.1" + }, + "dependencies": { + "package-json": { + "version": "4.0.1", + "bundled": true, + "requires": { + "got": "6.7.1", + "registry-auth-token": "3.3.1", + "registry-url": "3.1.0", + "semver": "5.5.0" + }, + "dependencies": { + "got": { + "version": "6.7.1", + "bundled": true, + "requires": { + "create-error-class": "3.0.2", + "duplexer3": "0.1.4", + "get-stream": "3.0.0", + "is-redirect": "1.0.0", + "is-retry-allowed": "1.1.0", + "is-stream": "1.1.0", + "lowercase-keys": "1.0.0", + "safe-buffer": "5.1.1", + "timed-out": "4.0.1", + "unzip-response": "2.0.1", + "url-parse-lax": "1.0.0" + }, + "dependencies": { + "create-error-class": { + "version": "3.0.2", + "bundled": true, + "requires": { + "capture-stack-trace": "1.0.0" + }, + "dependencies": { + "capture-stack-trace": { + "version": "1.0.0", + "bundled": true + } + } + }, + "duplexer3": { + "version": "0.1.4", + "bundled": true + }, + "get-stream": { + "version": "3.0.0", + "bundled": true + }, + "is-redirect": { + "version": "1.0.0", + "bundled": true + }, + "is-retry-allowed": { + "version": "1.1.0", + "bundled": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true + }, + "lowercase-keys": { + "version": "1.0.0", + "bundled": true + }, + "timed-out": { + "version": "4.0.1", + "bundled": true + }, + "unzip-response": { + "version": "2.0.1", + "bundled": true + }, + "url-parse-lax": { + "version": "1.0.0", + "bundled": true, + "requires": { + "prepend-http": "1.0.4" + }, + "dependencies": { + "prepend-http": { + "version": "1.0.4", + "bundled": true + } + } + } + } + }, + "registry-auth-token": { + "version": "3.3.1", + "bundled": true, + "requires": { + "rc": "1.2.1", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "rc": { + "version": "1.2.1", + "bundled": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "deep-extend": { + "version": "0.4.2", + "bundled": true + }, + "minimist": { + "version": "1.2.0", + "bundled": true + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true + } + } + } + } + }, + "registry-url": { + "version": "3.1.0", + "bundled": true, + "requires": { + "rc": "1.2.1" + }, + "dependencies": { + "rc": { + "version": "1.2.1", + "bundled": true, + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "deep-extend": { + "version": "0.4.2", + "bundled": true + }, + "minimist": { + "version": "1.2.0", + "bundled": true + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true + } + } + } + } + } + } + } + } + }, + "semver-diff": { + "version": "2.1.0", + "bundled": true, + "requires": { + "semver": "5.5.0" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "bundled": true + } + } + }, + "uuid": { + "version": "3.2.1", + "bundled": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "bundled": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + }, + "dependencies": { + "spdx-correct": { + "version": "1.0.2", + "bundled": true, + "requires": { + "spdx-license-ids": "1.2.2" + }, + "dependencies": { + "spdx-license-ids": { + "version": "1.2.2", + "bundled": true + } + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "bundled": true + } + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "bundled": true, + "requires": { + "builtins": "1.0.3" + }, + "dependencies": { + "builtins": { + "version": "1.0.3", + "bundled": true + } + } + }, + "which": { + "version": "1.3.0", + "bundled": true, + "requires": { + "isexe": "2.0.0" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "bundled": true + } + } + }, + "worker-farm": { + "version": "1.5.4", + "bundled": true, + "requires": { + "errno": "0.1.7", + "xtend": "4.0.1" + }, + "dependencies": { + "errno": { + "version": "0.1.7", + "bundled": true, + "requires": { + "prr": "1.0.1" + }, + "dependencies": { + "prr": { + "version": "1.0.1", + "bundled": true + } + } + }, + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "write-file-atomic": { + "version": "2.3.0", + "bundled": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "signal-exit": "3.0.2" + }, + "dependencies": { + "signal-exit": { + "version": "3.0.2", + "bundled": true + } + } + } + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", diff --git a/package.json b/package.json index ac120eb..a314a05 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "name": "javascript-data-store", "version": "1.0.0", "description": "JSDS is a small and fast data store.", - "main": "webpack.config.js", "directories": { "test": "tests" }, @@ -26,7 +25,9 @@ "url": "https://github.com/rhyolight/JavaScript-Data-Store/issues" }, "homepage": "https://github.com/rhyolight/JavaScript-Data-Store#readme", - "dependencies": {}, + "dependencies": { + "npm": "^5.8.0" + }, "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.4", 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..5e3d1d2 100755 --- a/src/jsds.js +++ b/src/jsds.js @@ -20,604 +20,594 @@ * 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 ('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, + 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, type, fireOptions); + } } } - }; - - // 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) { + 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; } - if (!listener.key || !crit) { - return true; + } + if (!listener.key || !crit) { + return true; + } + if (!crit.key || crit.key.match(toRegex(listener.key))) { + 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 Date: Thu, 19 Apr 2018 09:04:41 -0700 Subject: [PATCH 2/7] 1.0.1: removed loggins --- package.json | 2 +- src/jsds.js | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/package.json b/package.json index a314a05..edc102a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-data-store", - "version": "1.0.0", + "version": "1.0.1", "description": "JSDS is a small and fast data store.", "directories": { "test": "tests" diff --git a/src/jsds.js b/src/jsds.js index 5e3d1d2..d89390b 100755 --- a/src/jsds.js +++ b/src/jsds.js @@ -453,10 +453,6 @@ fire = function(type, fireOptions) { // 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) { From cfd00b0553387e46657928e3833c238563093aaa Mon Sep 17 00:00:00 2001 From: rhyolight Date: Thu, 19 Apr 2018 14:20:10 -0700 Subject: [PATCH 3/7] 1.0.2: bugfix for set events with falsey values. --- docs/jsds-1.0.2.js | 107 +++++++++++++++++++++++++++++++++++++ package.json | 2 +- src/jsds.js | 2 +- tests/jsds_perf_tests.html | 2 +- tests/jsds_tests.html | 2 +- tests/jsds_tests.js | 9 ++++ 6 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 docs/jsds-1.0.2.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/package.json b/package.json index edc102a..ebe6aa0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-data-store", - "version": "1.0.1", + "version": "1.0.2", "description": "JSDS is a small and fast data store.", "directories": { "test": "tests" diff --git a/src/jsds.js b/src/jsds.js index d89390b..d65a1b8 100755 --- a/src/jsds.js +++ b/src/jsds.js @@ -443,7 +443,7 @@ fire = function(type, fireOptions) { } else if (fireOptions.result) { opts.callback.call(scope, fireOptions.result); } else { - opts.callback.call(scope, type, fireOptions); + opts.callback.call(scope, fireOptions.result); } } } diff --git a/tests/jsds_perf_tests.html b/tests/jsds_perf_tests.html index 06a80ae..71c5fc4 100644 --- a/tests/jsds_perf_tests.html +++ b/tests/jsds_perf_tests.html @@ -57,7 +57,7 @@
- + +











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 0764319..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 99% rename from tests/jsds_tests.js rename to tests/jsds_tests.js_ index f9d6c55..1f9e1e1 100644 --- a/tests/jsds_tests.js +++ b/tests/jsds_tests.js_ @@ -1072,9 +1072,20 @@ YUI.add('jsds_tests', function(Y) { value = v }); this.s.set('fountain', 0); - a.areSame(value, 0, 'zero value callback was given wrong set value') + 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) { From 586a51fc4c42c1af86150d93fdf4ab235b72b7b0 Mon Sep 17 00:00:00 2001 From: rhyolight Date: Thu, 7 Jun 2018 12:00:53 -0700 Subject: [PATCH 5/7] Updated tests from the stone age --- tests/jsds-tests.js | 1763 +++++++++++++++++++++---------------------- 1 file changed, 850 insertions(+), 913 deletions(-) diff --git a/tests/jsds-tests.js b/tests/jsds-tests.js index ce4e445..10e0987 100644 --- a/tests/jsds-tests.js +++ b/tests/jsds-tests.js @@ -3,6 +3,17 @@ const expect = require('chai').expect let JSDS = require('../src/jsds') +// Tests might use this store +let store +function setUp() { + if (store) { + store.remove() + delete store + } + store = JSDS.create('store') +} + + describe('upon creation', () => { it('Create Store', () => { @@ -61,19 +72,6 @@ describe('when tracking different stores', () => { describe('when storing and retrieving', () => { - let store - - function setUp() { - if (store) { - store.remove() - delete store - } - store = JSDS.create('store') - } - - function tearDown() { - } - it('Store String Value', () => { setUp() store.set('city', 'Cupertino') @@ -217,929 +215,868 @@ describe('when storing and retrieving', () => { }) 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']) }) -// testNamespaceStorage_CombinedDots_Deep: function() { -// 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'); -// -// a.isObject(result, 'result should have been an object'); -// -// result = store.get('stuff.animals.reptiles.lizards'); -// a.isUndefined(result, 'query for lizards should be undefined'); -// -// result = store.get('stuff', 'animals', 'reptiles', 'turtles'); -// a.isArray(result, 'result should have been an array'); -// a.areEqual(1, result.length, 'result should have length of 1'); -// a.areEqual('Victor', result[0]); -// -// result = store.get('stuff', 'animals', 'mammals', 'primates', 'humans'); -// -// a.isObject(result, 'result should have been an object'); -// a.areEqual(4, result.Taylors.length, 'result should have length of 4'); -// a.areEqual('Matt', result.Taylors[0]); -// a.areEqual('Romy', result.Taylors[3]); -// }, -// -// testNamespaceStorage_SeparatedNoDots_Deep: function() { -// 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'); -// -// a.isObject(result, 'result should have been an object'); -// -// result = store.get('stuff.animals.reptiles.turtles'); -// a.isArray(result, 'result should have been an array'); -// a.areEqual(1, result.length, 'result should have length of 1'); -// a.areEqual('Victor', result[0]); -// -// result = store.get('stuff.animals.mammals.primates.humans'); -// -// a.isObject(result, 'result should have been an object'); -// a.areEqual(4, result.Taylors.length, 'result should have length of 4'); -// a.areEqual('Matt', result.Taylors[0]); -// a.areEqual('Romy', result.Taylors[3]); -// }, -// -// testNamespaceStorage_COMBO_Deep: function() { -// 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'); -// -// a.isObject(result, 'result should have been an object'); -// -// result = store.get('stuff.animals', 'reptiles.turtles'); -// a.isArray(result, 'result should have been an array'); -// a.areEqual(1, result.length, 'result should have length of 1'); -// a.areEqual('Victor', result[0]); -// -// result = store.get('stuff', 'animals.mammals.primates' , 'humans'); -// -// a.isObject(result, 'result should have been an object'); -// a.areEqual(4, result.Taylors.length, 'result should have length of 4'); -// a.areEqual('Matt', result.Taylors[0]); -// a.areEqual('Romy', result.Taylors[3]); -// }, -// -// testStoreIntoNonExistantNamespace: function() { -// store.set('stuff.test', 'pygmies'); -// let result = store.get('stuff', 'test'); -// a.areEqual('pygmies', result); -// }, -// -// testStoreReturnsPreviousValue_FromNestedNamespace: function() { -// store.set('stuff.test', 'pygmies'); -// let old = store.set('stuff.test', 'kidneys'); -// a.areEqual('pygmies', old); -// }, -// -// testClear: function() { -// store.set('stuff', 'frogs'); -// a.areEqual('frogs', store.get('stuff')); -// store.clear(); -// a.isUndefined(store.get('stuff')); -// }, -// -// testDelete: function() { -// let soonDeleted = JSDS.create('removeme'); -// soonDeleted.remove(); -// a.isUndefined(JSDS._stores['removeme']); -// }, -// -// testStoreHugeTextBlob: function() { -// let blob = '















Twitter / Home