diff --git a/.babelrc b/.babelrc index 7c24b2a..974f3e4 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,27 @@ { - "presets": ["stage-1", "es2015", "react"] + "presets": [ + [ + "env", + { + "modules": false, + "loose": true + } + ], + "stage-1", + "react" + ], + "env": { + "test": { + "presets": [ + [ + "env", + { + "loose": true + } + ], + "stage-1", + "react" + ] + } + } } diff --git a/.gitignore b/.gitignore index d89076d..31fd746 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ node_modules run-browserstack-tests.sh -bundle.js \ No newline at end of file +bundle.js +dist diff --git a/index.js b/index.js deleted file mode 100644 index fa08936..0000000 --- a/index.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - Experiment: require("./lib/Experiment"), - Variant: require("./lib/Variant"), - emitter: require("./lib/emitter"), - experimentDebugger: require("./lib/debugger"), - mixpanelHelper: require("./lib/helpers/mixpanel"), - segmentHelper: require("./lib/helpers/segment") -}; diff --git a/lib/CoreExperiment.js b/lib/CoreExperiment.js deleted file mode 100644 index c9e91f8..0000000 --- a/lib/CoreExperiment.js +++ /dev/null @@ -1,98 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _react = require('react'); - -var _react2 = _interopRequireDefault(_react); - -var _warning = require('fbjs/lib/warning'); - -var _warning2 = _interopRequireDefault(_warning); - -var _emitter = require('./emitter'); - -var _emitter2 = _interopRequireDefault(_emitter); - -var _Variant = require('./Variant'); - -var _Variant2 = _interopRequireDefault(_Variant); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.default = _react2.default.createClass({ - displayName: "Pushtell.CoreExperiment", - propTypes: { - name: _react2.default.PropTypes.string.isRequired, - value: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.func]).isRequired - }, - win: function win() { - _emitter2.default.emitWin(this.props.name); - }, - getInitialState: function getInitialState() { - var _this = this; - - var children = {}; - _react2.default.Children.forEach(this.props.children, function (element) { - if (!_react2.default.isValidElement(element) || element.type.displayName !== "Pushtell.Variant") { - var error = new Error("Pushtell Experiment children must be Pushtell Variant components."); - error.type = "PUSHTELL_INVALID_CHILD"; - throw error; - } - children[element.props.name] = element; - _emitter2.default.addExperimentVariant(_this.props.name, element.props.name); - }); - _emitter2.default.emit("variants-loaded", this.props.name); - return { - variants: children - }; - }, - componentWillReceiveProps: function componentWillReceiveProps(nextProps) { - var _this2 = this; - - if (nextProps.value !== this.props.value || nextProps.children !== this.props.children) { - (function () { - var value = typeof nextProps.value === "function" ? nextProps.value() : nextProps.value; - var children = {}; - _react2.default.Children.forEach(nextProps.children, function (element) { - children[element.props.name] = element; - }); - _this2.setState({ - value: value, - variants: children - }); - })(); - } - }, - componentWillMount: function componentWillMount() { - var _this3 = this; - - var value = typeof this.props.value === "function" ? this.props.value() : this.props.value; - if (!this.state.variants[value]) { - if ("production" !== process.env.NODE_ENV) { - (0, _warning2.default)(true, 'Experiment “' + this.props.name + '” does not contain variant “' + value + '”'); - } - } - _emitter2.default._incrementActiveExperiments(this.props.name); - _emitter2.default.setActiveVariant(this.props.name, value); - _emitter2.default._emitPlay(this.props.name, value); - this.setState({ - value: value - }); - this.valueSubscription = _emitter2.default.addActiveVariantListener(this.props.name, function (experimentName, variantName) { - _this3.setState({ - value: variantName - }); - }); - }, - componentWillUnmount: function componentWillUnmount() { - _emitter2.default._decrementActiveExperiments(this.props.name); - this.valueSubscription.remove(); - }, - render: function render() { - return this.state.variants[this.state.value] || null; - } -}); -module.exports = exports['default']; \ No newline at end of file diff --git a/lib/Experiment.js b/lib/Experiment.js deleted file mode 100644 index 8f3498b..0000000 --- a/lib/Experiment.js +++ /dev/null @@ -1,103 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -var _react = require("react"); - -var _react2 = _interopRequireDefault(_react); - -var _CoreExperiment = require("./CoreExperiment"); - -var _CoreExperiment2 = _interopRequireDefault(_CoreExperiment); - -var _emitter = require("./emitter"); - -var _emitter2 = _interopRequireDefault(_emitter); - -var _crc = require("fbjs/lib/crc32"); - -var _crc2 = _interopRequireDefault(_crc); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var store = void 0; - -var noopStore = { - getItem: function getItem() {}, - setItem: function setItem() {} -}; - -if (typeof window !== 'undefined' && 'localStorage' in window && window['localStorage'] !== null) { - try { - var key = '__pushtell_react__'; - window.localStorage.setItem(key, key); - if (window.localStorage.getItem(key) !== key) { - store = noopStore; - } else { - window.localStorage.removeItem(key); - store = window.localStorage; - } - } catch (e) { - store = noopStore; - } -} else { - store = noopStore; -} - -_emitter2.default.addActiveVariantListener(function (experimentName, variantName, skipSave) { - if (skipSave) { - return; - } - store.setItem('PUSHTELL-' + experimentName, variantName); -}); - -exports.default = _react2.default.createClass({ - displayName: "Pushtell.Experiment", - propTypes: { - name: _react2.default.PropTypes.string.isRequired, - defaultVariantName: _react2.default.PropTypes.string, - userIdentifier: _react2.default.PropTypes.string - }, - win: function win() { - _emitter2.default.emitWin(this.props.name); - }, - getLocalStorageValue: function getLocalStorageValue() { - var activeValue = _emitter2.default.getActiveVariant(this.props.name); - if (typeof activeValue === "string") { - return activeValue; - } - var storedValue = store.getItem('PUSHTELL-' + this.props.name); - if (typeof storedValue === "string") { - _emitter2.default.setActiveVariant(this.props.name, storedValue, true); - return storedValue; - } - if (typeof this.props.defaultVariantName === 'string') { - _emitter2.default.setActiveVariant(this.props.name, this.props.defaultVariantName); - return this.props.defaultVariantName; - } - var variants = _emitter2.default.getSortedVariants(this.props.name); - var weights = _emitter2.default.getSortedVariantWeights(this.props.name); - var weightSum = weights.reduce(function (a, b) { - return a + b; - }, 0); - var weightedIndex = typeof this.props.userIdentifier === 'string' ? Math.abs((0, _crc2.default)(this.props.userIdentifier) % weightSum) : Math.floor(Math.random() * weightSum); - var randomValue = variants[variants.length - 1]; - for (var index = 0; index < weights.length; index++) { - weightedIndex -= weights[index]; - if (weightedIndex < 0) { - randomValue = variants[index]; - break; - } - } - _emitter2.default.setActiveVariant(this.props.name, randomValue); - return randomValue; - }, - render: function render() { - return _react2.default.createElement(_CoreExperiment2.default, _extends({}, this.props, { value: this.getLocalStorageValue })); - } -}); -module.exports = exports['default']; \ No newline at end of file diff --git a/lib/Variant.js b/lib/Variant.js deleted file mode 100644 index 1f046fa..0000000 --- a/lib/Variant.js +++ /dev/null @@ -1,30 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _react = require("react"); - -var _react2 = _interopRequireDefault(_react); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.default = _react2.default.createClass({ - displayName: "Pushtell.Variant", - propTypes: { - name: _react2.default.PropTypes.string.isRequired - }, - render: function render() { - if (_react2.default.isValidElement(this.props.children)) { - return this.props.children; - } else { - return _react2.default.createElement( - "span", - null, - this.props.children - ); - } - } -}); -module.exports = exports['default']; \ No newline at end of file diff --git a/lib/debugger.js b/lib/debugger.js deleted file mode 100644 index 0dcc59a..0000000 --- a/lib/debugger.js +++ /dev/null @@ -1,211 +0,0 @@ -'use strict'; - -var _react = require('react'); - -var _react2 = _interopRequireDefault(_react); - -var _reactDom = require('react-dom'); - -var _reactDom2 = _interopRequireDefault(_reactDom); - -var _emitter = require('./emitter'); - -var _emitter2 = _interopRequireDefault(_emitter); - -var _ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -if (process.env.NODE_ENV === "production" || !_ExecutionEnvironment.canUseDOM) { - module.exports = { - enable: function enable() {}, - disable: function disable() {} - }; -} else { - (function () { - var attachStyleSheet = function attachStyleSheet() { - style = document.createElement("style"); - style.appendChild(document.createTextNode("")); - document.head.appendChild(style); - function addCSSRule(selector, rules) { - if ("insertRule" in style.sheet) { - style.sheet.insertRule(selector + "{" + rules + "}", 0); - } else if ("addRule" in style.sheet) { - style.sheet.addRule(selector, rules, 0); - } - } - addCSSRule("#pushtell-debugger", "z-index: 25000"); - addCSSRule("#pushtell-debugger", "position: fixed"); - addCSSRule("#pushtell-debugger", "transform: translateX(-50%)"); - addCSSRule("#pushtell-debugger", "bottom: 0"); - addCSSRule("#pushtell-debugger", "left: 50%"); - addCSSRule("#pushtell-debugger ul", "margin: 0"); - addCSSRule("#pushtell-debugger ul", "padding: 0 0 0 20px"); - addCSSRule("#pushtell-debugger li", "margin: 0"); - addCSSRule("#pushtell-debugger li", "padding: 0"); - addCSSRule("#pushtell-debugger li", "font-size: 14px"); - addCSSRule("#pushtell-debugger li", "line-height: 14px"); - addCSSRule("#pushtell-debugger input", "float: left"); - addCSSRule("#pushtell-debugger input", "margin: 0 10px 0 0"); - addCSSRule("#pushtell-debugger input", "padding: 0"); - addCSSRule("#pushtell-debugger input", "cursor: pointer"); - addCSSRule("#pushtell-debugger label", "color: #999999"); - addCSSRule("#pushtell-debugger label", "margin: 0 0 10px 0"); - addCSSRule("#pushtell-debugger label", "cursor: pointer"); - addCSSRule("#pushtell-debugger label", "font-weight: normal"); - addCSSRule("#pushtell-debugger label.active", "color: #000000"); - addCSSRule("#pushtell-debugger .pushtell-experiment-name", "font-size: 16px"); - addCSSRule("#pushtell-debugger .pushtell-experiment-name", "color: #000000"); - addCSSRule("#pushtell-debugger .pushtell-experiment-name", "margin: 0 0 10px 0"); - addCSSRule("#pushtell-debugger .pushtell-production-build-note", "font-size: 10px"); - addCSSRule("#pushtell-debugger .pushtell-production-build-note", "color: #999999"); - addCSSRule("#pushtell-debugger .pushtell-production-build-note", "text-align: center"); - addCSSRule("#pushtell-debugger .pushtell-production-build-note", "margin: 10px -40px 0 -10px"); - addCSSRule("#pushtell-debugger .pushtell-production-build-note", "border-top: 1px solid #b3b3b3"); - addCSSRule("#pushtell-debugger .pushtell-production-build-note", "padding: 10px 10px 5px 10px"); - addCSSRule("#pushtell-debugger .pushtell-handle", "cursor: pointer"); - addCSSRule("#pushtell-debugger .pushtell-handle", "padding: 5px 10px 5px 10px"); - addCSSRule("#pushtell-debugger .pushtell-panel", "padding: 15px 40px 5px 10px"); - addCSSRule("#pushtell-debugger .pushtell-container", "font-size: 11px"); - addCSSRule("#pushtell-debugger .pushtell-container", "background-color: #ebebeb"); - addCSSRule("#pushtell-debugger .pushtell-container", "color: #000000"); - addCSSRule("#pushtell-debugger .pushtell-container", "box-shadow: 0px 0 5px rgba(0, 0, 0, 0.1)"); - addCSSRule("#pushtell-debugger .pushtell-container", "border-top: 1px solid #b3b3b3"); - addCSSRule("#pushtell-debugger .pushtell-container", "border-left: 1px solid #b3b3b3"); - addCSSRule("#pushtell-debugger .pushtell-container", "border-right: 1px solid #b3b3b3"); - addCSSRule("#pushtell-debugger .pushtell-container", "border-top-left-radius: 2px"); - addCSSRule("#pushtell-debugger .pushtell-container", "border-top-right-radius: 2px"); - addCSSRule("#pushtell-debugger .pushtell-close", "cursor: pointer"); - addCSSRule("#pushtell-debugger .pushtell-close", "font-size: 16px"); - addCSSRule("#pushtell-debugger .pushtell-close", "font-weight: bold"); - addCSSRule("#pushtell-debugger .pushtell-close", "color: #CC0000"); - addCSSRule("#pushtell-debugger .pushtell-close", "position: absolute"); - addCSSRule("#pushtell-debugger .pushtell-close", "top: 0px"); - addCSSRule("#pushtell-debugger .pushtell-close", "right: 7px"); - addCSSRule("#pushtell-debugger .pushtell-close:hover", "color: #FF0000"); - addCSSRule("#pushtell-debugger .pushtell-close, #pushtell-debugger label", "transition: all .25s"); - }; - - var removeStyleSheet = function removeStyleSheet() { - if (style !== null) { - document.head.removeChild(style); - style = null; - } - }; - - var style = null; - - var Debugger = _react2.default.createClass({ - displayName: "Pushtell.Debugger", - getInitialState: function getInitialState() { - return { - experiments: _emitter2.default.getActiveExperiments(), - visible: false - }; - }, - toggleVisibility: function toggleVisibility() { - this.setState({ - visible: !this.state.visible - }); - }, - updateExperiments: function updateExperiments() { - this.setState({ - experiments: _emitter2.default.getActiveExperiments() - }); - }, - setActiveVariant: function setActiveVariant(experimentName, variantName) { - _emitter2.default.setActiveVariant(experimentName, variantName); - }, - componentWillMount: function componentWillMount() { - this.activeSubscription = _emitter2.default.addListener("active", this.updateExperiments); - this.inactiveSubscription = _emitter2.default.addListener("inactive", this.updateExperiments); - }, - componentWillUnmount: function componentWillUnmount() { - this.activeSubscription.remove(); - this.inactiveSubscription.remove(); - }, - render: function render() { - var _this = this; - - var experimentNames = Object.keys(this.state.experiments); - if (this.state.visible) { - return _react2.default.createElement( - 'div', - { className: 'pushtell-container pushtell-panel' }, - _react2.default.createElement( - 'div', - { className: 'pushtell-close', onClick: this.toggleVisibility }, - '×' - ), - experimentNames.map(function (experimentName) { - var variantNames = Object.keys(_this.state.experiments[experimentName]); - if (variantNames.length === 0) { - return; - } - return _react2.default.createElement( - 'div', - { className: 'pushtell-experiment', key: experimentName }, - _react2.default.createElement( - 'div', - { className: 'pushtell-experiment-name' }, - experimentName - ), - _react2.default.createElement( - 'ul', - null, - variantNames.map(function (variantName) { - return _react2.default.createElement( - 'li', - { key: variantName }, - _react2.default.createElement( - 'label', - { className: _this.state.experiments[experimentName][variantName] ? "active" : null, onClick: _this.setActiveVariant.bind(_this, experimentName, variantName) }, - _react2.default.createElement('input', { type: 'radio', name: experimentName, value: variantName, defaultChecked: _this.state.experiments[experimentName][variantName] }), - variantName - ) - ); - }) - ) - ); - }), - _react2.default.createElement( - 'div', - { className: 'pushtell-production-build-note' }, - 'This panel is hidden on production builds.' - ) - ); - } else if (experimentNames.length > 0) { - return _react2.default.createElement( - 'div', - { className: 'pushtell-container pushtell-handle', onClick: this.toggleVisibility }, - experimentNames.length, - ' Active Experiment', - experimentNames.length > 1 ? "s" : "" - ); - } else { - return null; - } - } - }); - - module.exports = { - enable: function enable() { - attachStyleSheet(); - var body = document.getElementsByTagName('body')[0]; - var container = document.createElement('div'); - container.id = 'pushtell-debugger'; - body.appendChild(container); - _reactDom2.default.render(_react2.default.createElement(Debugger, null), container); - }, - disable: function disable() { - removeStyleSheet(); - var body = document.getElementsByTagName('body')[0]; - var container = document.getElementById('pushtell-debugger'); - if (container) { - _reactDom2.default.unmountComponentAtNode(container); - body.removeChild(container); - } - } - }; - })(); -} \ No newline at end of file diff --git a/lib/emitter.js b/lib/emitter.js deleted file mode 100644 index cd74a08..0000000 --- a/lib/emitter.js +++ /dev/null @@ -1,206 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _fbemitter = require('fbemitter'); - -var values = {}; -var experiments = {}; -var experimentWeights = {}; -var activeExperiments = {}; -var experimentsWithDefinedVariants = {}; -var playedExperiments = {}; - -var emitter = new _fbemitter.EventEmitter(); - -var PushtellEventEmitter = function PushtellEventEmitter() {}; - -PushtellEventEmitter.prototype.emitWin = function (experimentName) { - if (typeof experimentName !== 'string') { - throw new Error("Required argument 'experimentName' should have type 'string'"); - } - emitter.emit("win", experimentName, values[experimentName]); -}; - -PushtellEventEmitter.prototype._emitPlay = function (experimentName, variantName) { - if (typeof experimentName !== 'string') { - throw new Error("Required argument 'experimentName' should have type 'string'"); - } - if (typeof variantName !== 'string') { - throw new Error("Required argument 'variantName' should have type 'string'"); - } - if (!playedExperiments[experimentName]) { - emitter.emit('play', experimentName, variantName); - playedExperiments[experimentName] = true; - } -}; - -PushtellEventEmitter.prototype._resetPlayedExperiments = function () { - values = {}; - playedExperiments = {}; -}; - -PushtellEventEmitter.prototype._reset = function () { - values = {}; - experiments = {}; - experimentWeights = {}; - activeExperiments = {}; - experimentsWithDefinedVariants = {}; - playedExperiments = {}; -}; - -PushtellEventEmitter.prototype.rewind = function () { - this._reset(); - emitter.removeAllListeners(); -}; - -PushtellEventEmitter.prototype._incrementActiveExperiments = function (experimentName) { - activeExperiments[experimentName] = activeExperiments[experimentName] || 0; - activeExperiments[experimentName] += 1; - emitter.emit("active", experimentName); -}; - -PushtellEventEmitter.prototype._decrementActiveExperiments = function (experimentName) { - activeExperiments[experimentName] -= 1; - emitter.emit("inactive", experimentName); -}; - -PushtellEventEmitter.prototype.addActiveVariantListener = function (experimentName, callback) { - if (typeof experimentName === "function") { - callback = experimentName; - return emitter.addListener("active-variant", function (_experimentName, variantName, passthrough) { - callback(_experimentName, variantName, passthrough); - }); - } - return emitter.addListener("active-variant", function (_experimentName, variantName, passthrough) { - if (_experimentName === experimentName) { - callback(_experimentName, variantName, passthrough); - } - }); -}; - -PushtellEventEmitter.prototype.emit = function () { - return emitter.emit.apply(emitter, arguments); -}; - -PushtellEventEmitter.prototype.addListener = function (eventName, callback) { - return emitter.addListener(eventName, callback); -}; - -PushtellEventEmitter.prototype.once = function (eventName, callback) { - return emitter.once(eventName, callback); -}; - -PushtellEventEmitter.prototype.addPlayListener = function (experimentName, callback) { - if (typeof experimentName === "function") { - callback = experimentName; - return emitter.addListener('play', function (_experimentName, variantName) { - callback(_experimentName, variantName); - }); - } - return emitter.addListener('play', function (_experimentName, variantName) { - if (_experimentName === experimentName) { - callback(_experimentName, variantName); - } - }); -}; - -PushtellEventEmitter.prototype.addWinListener = function (experimentName, callback) { - if (typeof experimentName === "function") { - callback = experimentName; - return emitter.addListener('win', function (_experimentName, variantName) { - callback(_experimentName, variantName); - }); - } - return emitter.addListener('win', function (_experimentName, variantName) { - if (_experimentName === experimentName) { - callback(_experimentName, variantName); - } - }); -}; - -PushtellEventEmitter.prototype.defineVariants = function (experimentName, variantNames, variantWeights) { - var variantsNamesMap = {}; - var variantWeightsMap = {}; - variantNames.forEach(function (variantName) { - variantsNamesMap[variantName] = true; - }); - if (Array.isArray(variantWeights)) { - if (variantNames.length !== variantWeights.length) { - throw new Error("Required argument 'variantNames' should have the same number of elements as optional argument 'variantWeights'"); - } - variantNames.forEach(function (variantName, index) { - if (typeof variantWeights[index] !== 'number') { - throw new Error("Optional argument 'variantWeights' should be an array of numbers."); - } - variantWeightsMap[variantName] = variantWeights[index]; - }); - } else { - variantNames.forEach(function (variantName, index) { - variantWeightsMap[variantName] = 1; - }); - } - experimentWeights[experimentName] = variantWeightsMap; - experiments[experimentName] = variantsNamesMap; - experimentsWithDefinedVariants[experimentName] = true; -}; - -PushtellEventEmitter.prototype.getSortedVariants = function (experimentName) { - var variantNames = Object.keys(experiments[experimentName]); - variantNames.sort(); - return variantNames; -}; - -PushtellEventEmitter.prototype.getSortedVariantWeights = function (experimentName) { - return this.getSortedVariants(experimentName).map(function (variantName) { - return experimentWeights[experimentName][variantName]; - }); -}; - -PushtellEventEmitter.prototype.getActiveExperiments = function () { - var response = {}; - Object.keys(activeExperiments).forEach(function (experimentName) { - if (activeExperiments[experimentName] === 0) { - return; - } - response[experimentName] = {}; - Object.keys(experiments[experimentName]).forEach(function (variantName) { - response[experimentName][variantName] = values[experimentName] === variantName; - }); - }); - return response; -}; - -PushtellEventEmitter.prototype.getActiveVariant = function (experimentName) { - return values[experimentName]; -}; - -PushtellEventEmitter.prototype.setActiveVariant = function (experimentName, variantName, passthrough) { - values[experimentName] = variantName; - emitter.emit("active-variant", experimentName, variantName, passthrough); -}; - -PushtellEventEmitter.prototype.addExperimentVariant = function (experimentName, variantName) { - experiments[experimentName] = experiments[experimentName] || {}; - experimentWeights[experimentName] = experimentWeights[experimentName] || {}; - if (experiments[experimentName][variantName] !== true) { - if (experimentsWithDefinedVariants[experimentName]) { - var error = new Error("Experiment “" + experimentName + "” added new variants after variants were defined."); - error.type = "PUSHTELL_INVALID_VARIANT"; - throw error; - } - if (values[experimentName]) { - var _error = new Error("Experiment “" + experimentName + "” added new variants after a variant was selected. Declare the variant names using emitter.defineVariants(experimentName, variantNames)."); - _error.type = "PUSHTELL_INVALID_VARIANT"; - throw _error; - } - experimentWeights[experimentName][variantName] = 1; - } - experiments[experimentName][variantName] = true; -}; - -exports.default = new PushtellEventEmitter(); -; -module.exports = exports['default']; \ No newline at end of file diff --git a/lib/helpers/mixpanel.js b/lib/helpers/mixpanel.js deleted file mode 100644 index c494012..0000000 --- a/lib/helpers/mixpanel.js +++ /dev/null @@ -1,56 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _emitter = require("../emitter"); - -var _emitter2 = _interopRequireDefault(_emitter); - -var _ExecutionEnvironment = require("fbjs/lib/ExecutionEnvironment"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var playSubscription = void 0, - winSubscription = void 0; - -exports.default = { - enable: function enable() { - if (_ExecutionEnvironment.canUseDOM) { - if (typeof mixpanel === "undefined") { - var error = new Error("React A/B Test Mixpanel Helper: 'mixpanel' global is not defined."); - error.type = "PUSHTELL_HELPER_MISSING_GLOBAL"; - throw error; - } - playSubscription = _emitter2.default.addPlayListener(function (experimentName, variantName) { - mixpanel.track("Experiment Play", { - "Experiment": experimentName, - "Variant": variantName - }, function () { - _emitter2.default.emit("mixpanel-play", experimentName, variantName); - }); - }); - winSubscription = _emitter2.default.addWinListener(function (experimentName, variantName) { - mixpanel.track("Experiment Win", { - "Experiment": experimentName, - "Variant": variantName - }, function () { - _emitter2.default.emit("mixpanel-win", experimentName, variantName); - }); - }); - } - }, - disable: function disable() { - if (_ExecutionEnvironment.canUseDOM) { - if (!playSubscription || !winSubscription) { - var error = new Error("React A/B Test Mixpanel Helper: Helper was not enabled."); - error.type = "PUSHTELL_HELPER_INVALID_DISABLE"; - throw error; - } - playSubscription.remove(); - winSubscription.remove(); - } - } -}; -module.exports = exports['default']; \ No newline at end of file diff --git a/lib/helpers/segment.js b/lib/helpers/segment.js deleted file mode 100644 index 5005f12..0000000 --- a/lib/helpers/segment.js +++ /dev/null @@ -1,56 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _emitter = require("../emitter"); - -var _emitter2 = _interopRequireDefault(_emitter); - -var _ExecutionEnvironment = require("fbjs/lib/ExecutionEnvironment"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var playSubscription = void 0, - winSubscription = void 0; - -exports.default = { - enable: function enable() { - if (_ExecutionEnvironment.canUseDOM) { - if (typeof analytics === "undefined") { - var error = new Error("React A/B Test Segment Helper: 'analytics' global is not defined."); - error.type = "PUSHTELL_HELPER_MISSING_GLOBAL"; - throw error; - } - playSubscription = _emitter2.default.addPlayListener(function (experimentName, variantName) { - analytics.track("Experiment Viewed", { - "experimentName": experimentName, - "variationName": variantName - }, function () { - _emitter2.default.emit("segment-play", experimentName, variantName); - }); - }); - winSubscription = _emitter2.default.addWinListener(function (experimentName, variantName) { - analytics.track("Experiment Won", { - "experimentName": experimentName, - "variationName": variantName - }, function () { - _emitter2.default.emit("segment-win", experimentName, variantName); - }); - }); - } - }, - disable: function disable() { - if (_ExecutionEnvironment.canUseDOM) { - if (!playSubscription || !winSubscription) { - var error = new Error("React A/B Test Segment Helper: Helper was not enabled."); - error.type = "PUSHTELL_HELPER_INVALID_DISABLE"; - throw error; - } - playSubscription.remove(); - winSubscription.remove(); - } - } -}; -module.exports = exports['default']; \ No newline at end of file diff --git a/package.json b/package.json index 5b9f5ea..9d3a318 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,11 @@ { "name": "react-ab-test", + "description": "A/B testing React components and debug tools. Isomorphic with a simple, universal interface. Well documented and lightweight. Tested in popular browsers and Node.js. Includes helpers for Mixpanel and Segment.com.", + "jsnext:main": "dist/react-ab-test.es.js", + "module": "dist/react-ab-test.es.js", + "main": "dist/react-ab-test.js", + "umd:main": "dist/react-ab-test.umd.js", + "version": "1.8.1", "keywords": [ "react", "react-component", @@ -10,9 +16,6 @@ "A/B testing", "A/B test" ], - "main": "index.js", - "version": "1.9.0", - "description": "A/B testing React components and debug tools. Isomorphic with a simple, universal interface. Well documented and lightweight. Tested in popular browsers and Node.js. Includes helpers for Mixpanel and Segment.com.", "directories": { "test": "test" }, @@ -31,6 +34,7 @@ "babel-loader": "^6.2.4", "babel-plugin-add-module-exports": "^0.1.2", "babel-polyfill": "^6.7.4", + "babel-preset-env": "^1.4.0", "babel-preset-es2015": "^6.6.0", "babel-preset-react": "^6.5.0", "babel-preset-stage-1": "^6.5.0", @@ -57,6 +61,7 @@ "karma-webpack": "^1.7.0", "mocha": "^2.4.5", "node-uuid": "^1.4.7", + "npm-run-all": "^4.0.2", "react": "^15.0.1", "react-dom": "^15.0.1", "regenerator": "^0.8.42", @@ -67,6 +72,11 @@ "scripts": { "test": "./node_modules/karma/bin/karma start test/browser/karma.conf.js; mocha --require babel-core/register --require babel-polyfill test/isomorphic/*.jsx", "build": "./node_modules/.bin/doctoc . --github --title '

Table of Contents

'; ./node_modules/babel-cli/bin/babel.js --presets es2015,stage-1,react --plugins add-module-exports ./src --out-dir ./lib; ./node_modules/webpack/bin/webpack.js --config webpack.standalone.config.js", + "clean": "rimraf dist", + "size": "echo \"Gzipped Size: $(strip-json-comments --no-whitespace $npm_package_main | gzip-size)\"", + "rollup": "rollup -c", + "minify:cjs": "uglifyjs $npm_package_main -cm toplevel -o $npm_package_main -p relative --in-source-map ${npm_package_main}.map --source-map ${npm_package_main}.map", + "minify:umd": "uglifyjs $npm_package_umd_main -cm -o $npm_package_umd_main -p relative --in-source-map ${npm_package_umd_main}.map --source-map ${npm_package_umd_main}.map", "lint": "eslint .", "lint:fix": "eslint --fix ." }, diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..e989d24 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,28 @@ +import babel from 'rollup-plugin-babel'; +import fs from 'fs' + +const pkg = JSON.parse(fs.readFileSync('./package.json')) + +export default { + entry: 'src/index.js', + external: [ + 'react', + 'react-dom', + 'fbjs/lib/warning', + 'fbjs/lib/crc32', + 'fbjs/lib/ExecutionEnvironment', + 'fbemitter' + ], + exports: 'named', + globals: { react: 'React' }, + useStrict: false, + sourceMap: true, + plugins: [babel({ + exclude: 'node_modules/**' + })], + targets: [ + {dest: pkg.main, format: 'cjs'}, + {dest: pkg.module, format: 'es'}, + {dest: pkg['umd:main'], format: 'umd', moduleName: pkg.name} + ] +} diff --git a/src/CoreExperiment.jsx b/src/CoreExperiment.jsx index efc4f22..69f876c 100644 --- a/src/CoreExperiment.jsx +++ b/src/CoreExperiment.jsx @@ -1,7 +1,7 @@ import React from 'react'; import warning from 'fbjs/lib/warning'; -import emitter from "./emitter"; -import Variant from "./Variant"; +import emitter from "./emitter.jsx"; +import Variant from "./Variant.jsx"; export default React.createClass({ displayName: "Pushtell.CoreExperiment", diff --git a/src/Experiment.jsx b/src/Experiment.jsx index 5175465..bafcc0e 100644 --- a/src/Experiment.jsx +++ b/src/Experiment.jsx @@ -1,6 +1,6 @@ import React from "react"; -import CoreExperiment from "./CoreExperiment"; -import emitter from "./emitter"; +import CoreExperiment from "./CoreExperiment.jsx"; +import emitter from "./emitter.jsx"; import crc32 from "fbjs/lib/crc32"; let store; @@ -76,4 +76,4 @@ export default React.createClass({ render() { return ; } -}); \ No newline at end of file +}); diff --git a/src/debugger.jsx b/src/debugger.jsx index ffc00ab..906b842 100644 --- a/src/debugger.jsx +++ b/src/debugger.jsx @@ -1,6 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import emitter from "./emitter"; +import emitter from "./emitter.jsx"; import {canUseDOM} from 'fbjs/lib/ExecutionEnvironment'; if(process.env.NODE_ENV === "production" || !canUseDOM) { @@ -143,7 +143,7 @@ if(process.env.NODE_ENV === "production" || !canUseDOM) { } }); - module.exports = { +const debuggerExport = { enable() { attachStyleSheet(); let body = document.getElementsByTagName('body')[0]; @@ -163,3 +163,5 @@ if(process.env.NODE_ENV === "production" || !canUseDOM) { } } } + +export default debuggerExport; diff --git a/src/helpers/mixpanel.jsx b/src/helpers/mixpanel.jsx index 8552540..e6142b6 100644 --- a/src/helpers/mixpanel.jsx +++ b/src/helpers/mixpanel.jsx @@ -1,4 +1,4 @@ -import emitter from "../emitter"; +import emitter from "../emitter.jsx"; import {canUseDOM} from 'fbjs/lib/ExecutionEnvironment'; let playSubscription, winSubscription; diff --git a/src/helpers/segment.jsx b/src/helpers/segment.jsx index fae76b8..c13b795 100644 --- a/src/helpers/segment.jsx +++ b/src/helpers/segment.jsx @@ -1,4 +1,4 @@ -import emitter from "../emitter"; +import emitter from "../emitter.jsx"; import {canUseDOM} from 'fbjs/lib/ExecutionEnvironment'; let playSubscription, winSubscription; diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..05fd05e --- /dev/null +++ b/src/index.js @@ -0,0 +1,15 @@ +import Experiment from './Experiment.jsx'; +import Variant from './Variant.jsx'; +import emitter from './emitter.jsx'; +import experimentDebugger from './debugger.jsx'; +import mixpanelHelper from './helpers/mixpanel.jsx'; +import segmentHelper from './helpers/segment.jsx'; + +export default { + Experiment, + Variant, + emitter, + experimentDebugger, + mixpanelHelper, + segmentHelper +}