From ea63eab1042f252327d9b022273ef9d0ca46d3e8 Mon Sep 17 00:00:00 2001 From: Jay Winstead Date: Sun, 1 Oct 2017 11:09:30 -0500 Subject: [PATCH] refactor to use feature store event wrapper --- feature_store.js | 42 ++--- feature_store_event_wrapper.js | 52 ++++++ index.js | 5 +- package-lock.json | 327 +++++++++++++++++++++++++++++++++ package.json | 1 - yarn.lock | 236 ++++++++++++++++++++++++ 6 files changed, 630 insertions(+), 33 deletions(-) create mode 100644 feature_store_event_wrapper.js create mode 100644 package-lock.json create mode 100644 yarn.lock diff --git a/feature_store.js b/feature_store.js index 710264a..95cbd5e 100644 --- a/feature_store.js +++ b/feature_store.js @@ -1,9 +1,8 @@ -var deepEqual = require('deep-equal'); // An in-memory feature store with an async interface. // It's async as other implementations (e.g. the RedisFeatureStore) // may be async, and we want to retain interface compatibility. var noop = function(){}; -function InMemoryFeatureStore(emitter) { +function InMemoryFeatureStore() { var store = {flags:{}}; store.get = function(key, cb) { @@ -40,16 +39,7 @@ function InMemoryFeatureStore(emitter) { store.init = function(flags, cb) { cb = cb || noop; - - var oldFlags = this.flags; this.flags = flags; - - for (var key in oldFlags) { - if (oldFlags.hasOwnProperty(key)) { - differ(key, oldFlags[key], flags[key]); - } - } - this.init_called = true; cb(); } @@ -57,47 +47,37 @@ function InMemoryFeatureStore(emitter) { store.delete = function(key, version, cb) { cb = cb || noop; - var oldFlag = this.flags[key]; - if (this.flags.hasOwnProperty(key)) { - if (oldFlag && oldFlag.version < version) { - oldFlag.deleted = true; - oldFlag.version = version; - this.flags[key] = oldFlag; + var old = this.flags[key]; + if (old && old.version < version) { + old.deleted = true; + old.version = version; + this.flags[key] = old; } } else { - this.flags[key] = oldFlag; + this.flags[key] = old; } - differ(key, oldFlag, {}); cb(); } store.upsert = function(key, flag, cb) { - cb = cb || noop; - - var oldFlag = this.flags[key]; + cb = cb || noop; + var old = this.flags[key]; if (this.flags.hasOwnProperty(key)) { - if (oldFlag && oldFlag.version < flag.version) { + var old = this.flags[key]; + if (old && old.version < flag.version) { this.flags[key] = flag; } } else { this.flags[key] = flag; } - differ(key, oldFlag, flag); - cb(); } - function differ(key, oldValue, newValue) { - if(deepEqual(oldValue, newValue)) return; - emitter.emit("update", newValue); - emitter.emit(`update:${key}`, oldValue, newValue); - } - store.initialized = function() { return this.init_called === true; } diff --git a/feature_store_event_wrapper.js b/feature_store_event_wrapper.js new file mode 100644 index 0000000..2ede820 --- /dev/null +++ b/feature_store_event_wrapper.js @@ -0,0 +1,52 @@ +function FeatureStoreEventWrapper(featureStore, emitter) { + function differ(key, oldValue, newValue) { + if(newValue.version < oldValue.version) return; + emitter.emit("update", newValue); + emitter.emit(`update:${key}`, oldValue, newValue); + } + + return { + get: featureStore.get, + all: featureStore.all, + initialized: featureStore.initialized, + close: featureStore.close, + + init: function(newFlags, callback) { + featureStore.all(function(oldFlags){ + featureStore.init(newFlags, function(){ + var allFlags = newFlags.concat(oldFlags); + var handledFlags = {}; + + for (var key in allFlags) { + if(handledFlags[key]) continue; + differ(key, oldFlags[key], flags[key]); + handledFlags[key] = true; + ; + } + + callback && callback.apply(null, arguments); + }); + }); + }, + + delete: function(key, version, callback) { + featureStore.get(function(oldFlag) { + featureStore.delete(key, version, function() { + differ(key, oldFlag, {}); + callback && callback.apply(null, arguments); + }); + }); + }, + + upsert: function(key, flag, callback) { + featureStore.get(function(oldFlag) { + featureStore.upsert(key, newFlag, function() { + differ(key, oldFlag, newFlag); + callback && callback.apply(null, arguments); + }); + }); + } + } +} + +module.exports = FeatureStoreEventWrapper; \ No newline at end of file diff --git a/index.js b/index.js index 67681f5..6e5005c 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,5 @@ var requestify = require('requestify'); +var FeatureStoreEventWrapper = require('./feature_store_event_wrapper'); var InMemoryFeatureStore = require('./feature_store'); var RedisFeatureStore = require('./redis_feature_store'); var Requestor = require('./requestor'); @@ -87,7 +88,9 @@ var new_client = function(sdk_key, config) { ] }) ); - config.feature_store = config.feature_store || InMemoryFeatureStore(client); + + var featureStore = config.feature_store || InMemoryFeatureStore(); + config.feature_store = FeatureStoreEventWrapper(featureStore, client); var maybeReportError = createErrorReporter(client, config.logger); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9ffbbce --- /dev/null +++ b/package-lock.json @@ -0,0 +1,327 @@ +{ + "name": "ldclient-node", + "version": "3.0.15", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "requires": { + "lodash": "4.17.4" + } + }, + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=" + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" + }, + "commander": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", + "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", + "dev": true + }, + "crypto": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-0.0.3.tgz", + "integrity": "sha1-RwqBuGvkxe4XrMggeh9TFa4g27A=" + }, + "cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + }, + "diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "dev": true + }, + "double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + }, + "escape-string-regexp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", + "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", + "dev": true + }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + }, + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimatch": "0.3.0" + } + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jade": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", + "dev": true, + "requires": { + "commander": "0.6.1", + "mkdirp": "0.3.0" + }, + "dependencies": { + "commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", + "dev": true + }, + "mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", + "dev": true + } + } + }, + "jquery": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-1.11.3.tgz", + "integrity": "sha1-3Yt0J4snEC0p32Pq4oMIqM+htYM=" + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", + "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", + "dev": true, + "requires": { + "commander": "2.3.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.2", + "glob": "3.2.11", + "growl": "1.9.2", + "jade": "0.26.3", + "mkdirp": "0.5.1", + "supports-color": "1.2.0", + "to-iso-string": "0.0.2" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "node-cache": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-3.2.1.tgz", + "integrity": "sha1-p5WNMqikLZEZziWYZWfqLF+WZ3M=", + "requires": { + "clone": "1.0.2", + "lodash": "4.17.4" + } + }, + "node-sha1": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/node-sha1/-/node-sha1-0.0.1.tgz", + "integrity": "sha1-VmL8eZ8cPJXZPjAV3QSAZVFJhdM=" + }, + "original": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/original/-/original-0.0.8.tgz", + "integrity": "sha1-XQvMTGc5IXBeKohCzcoWhCcbrgw=", + "requires": { + "url-parse": "0.2.3" + } + }, + "q": { + "version": "0.9.7", + "resolved": "https://registry.npmjs.org/q/-/q-0.9.7.tgz", + "integrity": "sha1-TeLmyzspCIyeTLwDv51C+5bOL3U=" + }, + "querystringify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz", + "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=" + }, + "redis": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", + "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "requires": { + "double-ended-queue": "2.1.0-0", + "redis-commands": "1.3.1", + "redis-parser": "2.6.0" + } + }, + "redis-commands": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", + "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=" + }, + "redis-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", + "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" + }, + "requestify": { + "version": "https://github.com/launchdarkly/requestify/tarball/d7e23d3f05e55415f50c0970a7e61bea5336f18f", + "integrity": "sha1-Tasy47XxgiEDukfqD4Y7fFSOCk0=", + "requires": { + "jquery": "1.11.3", + "q": "0.9.7", + "underscore": "1.4.4" + } + }, + "requires-port": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-0.0.1.tgz", + "integrity": "sha1-S0QUQR2d98hVmV3YmajHiilRwW0=" + }, + "rewire": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/rewire/-/rewire-2.5.2.tgz", + "integrity": "sha1-ZCfee3/u+n02QBUH62SlOFvFjcc=", + "dev": true + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, + "supports-color": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", + "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", + "dev": true + }, + "to-iso-string": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", + "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", + "dev": true + }, + "tunnel": { + "version": "https://github.com/launchdarkly/node-tunnel/tarball/d860e57650cce1ea655d00854c81babe6b47e02c", + "integrity": "sha1-DxkgfzcgRtPUaCGDy+INSgR8zdk=" + }, + "underscore": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz", + "integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ=" + }, + "url-parse": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-0.2.3.tgz", + "integrity": "sha1-ANPW8LTk8xnqd/djxW8MTJUe0nM=", + "requires": { + "querystringify": "0.0.4", + "requires-port": "0.0.1" + } + }, + "winston": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.3.1.tgz", + "integrity": "sha1-C0hCDZeMAYBM8CMLZIhhWYIloRk=", + "requires": { + "async": "1.0.0", + "colors": "1.0.3", + "cycle": "1.0.3", + "eyes": "0.1.8", + "isstream": "0.1.2", + "stack-trace": "0.0.10" + }, + "dependencies": { + "async": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", + "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" + } + } + } + } +} diff --git a/package.json b/package.json index 69826e0..a8a21ca 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "dependencies": { "async": "^2.0.0-rc.5", "crypto": "0.0.3", - "deep-equal": "1.0.1", "node-cache": "^3.2.1", "node-sha1": "0.0.1", "original": "~0.0.8", diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..45ee446 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,236 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +async@^2.0.0-rc.5: + version "2.5.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" + dependencies: + lodash "^4.14.0" + +async@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" + +clone@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" + +colors@1.0.x: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + +commander@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + +commander@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" + +crypto@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/crypto/-/crypto-0.0.3.tgz#470a81b86be4c5ee17acc8207a1f5315ae20dbb0" + +cycle@1.0.x: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + +debug@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +diff@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + +double-ended-queue@^2.1.0-0: + version "2.1.0-0" + resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" + +escape-string-regexp@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + +eyes@0.1.x: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + +glob@3.2.11: + version "3.2.11" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + dependencies: + inherits "2" + minimatch "0.3" + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + +inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +isstream@0.1.x: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +jade@0.26.3: + version "0.26.3" + resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" + dependencies: + commander "0.6.1" + mkdirp "0.3.0" + +"jquery@ ~1.11": + version "1.11.3" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-1.11.3.tgz#dd8b74278b27102d29df63eae28308a8cfa1b583" + +lodash@4.x, lodash@^4.14.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + +minimatch@0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha@^2.4.5: + version "2.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" + dependencies: + commander "2.3.0" + debug "2.2.0" + diff "1.4.0" + escape-string-regexp "1.0.2" + glob "3.2.11" + growl "1.9.2" + jade "0.26.3" + mkdirp "0.5.1" + supports-color "1.2.0" + to-iso-string "0.0.2" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +node-cache@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-3.2.1.tgz#a7958d32a8a42d9119ce25986567ea2c5f966773" + dependencies: + clone "1.0.x" + lodash "4.x" + +node-sha1@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/node-sha1/-/node-sha1-0.0.1.tgz#5662fc799f1c3c95d93e3015dd048065514985d3" + +original@~0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/original/-/original-0.0.8.tgz#5d0bcc4c673921705e2a8842cdca1684271bae0c" + dependencies: + url-parse "0.2.x" + +q@~0.9.3: + version "0.9.7" + resolved "https://registry.yarnpkg.com/q/-/q-0.9.7.tgz#4de2e6cb3b29088c9e4cbc03bf9d42fb96ce2f75" + +querystringify@0.0.x: + version "0.0.4" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" + +redis-commands@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.3.1.tgz#81d826f45fa9c8b2011f4cd7a0fe597d241d442b" + +redis-parser@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b" + +redis@^2.6.0-2: + version "2.8.0" + resolved "https://registry.yarnpkg.com/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02" + dependencies: + double-ended-queue "^2.1.0-0" + redis-commands "^1.2.0" + redis-parser "^2.6.0" + +"requestify@https://github.com/launchdarkly/requestify/tarball/d7e23d3f05e55415f50c0970a7e61bea5336f18f": + version "0.2.0" + resolved "https://github.com/launchdarkly/requestify/tarball/d7e23d3f05e55415f50c0970a7e61bea5336f18f#4dab32e3b5f1822103ba47ea0f863b7c548e0a4d" + dependencies: + jquery " ~1.11" + q "~0.9.3" + underscore "~1.4.4" + +requires-port@0.0.x: + version "0.0.1" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-0.0.1.tgz#4b4414411d9df7c855995dd899a8c78a2951c16d" + +rewire@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/rewire/-/rewire-2.5.2.tgz#6427de7b7feefa7d36401507eb64a5385bc58dc7" + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + +supports-color@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" + +to-iso-string@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" + +"tunnel@https://github.com/launchdarkly/node-tunnel/tarball/d860e57650cce1ea655d00854c81babe6b47e02c": + version "0.0.4-pre" + resolved "https://github.com/launchdarkly/node-tunnel/tarball/d860e57650cce1ea655d00854c81babe6b47e02c#0f19207f372046d3d4682183cbe20d4a047ccdd9" + +underscore@~1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604" + +url-parse@0.2.x: + version "0.2.3" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-0.2.3.tgz#00d3d6f0b4e4f319ea77f763c56f0c4c951ed273" + dependencies: + querystringify "0.0.x" + requires-port "0.0.x" + +winston@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/winston/-/winston-2.3.1.tgz#0b48420d978c01804cf0230b648861598225a119" + dependencies: + async "~1.0.0" + colors "1.0.x" + cycle "1.0.x" + eyes "0.1.x" + isstream "0.1.x" + stack-trace "0.0.x"