react-hot-loader
Version:
Tweak React components in real time.
1,616 lines (1,346 loc) • 101 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var React = require('react');
var React__default = _interopDefault(React);
var shallowEqual = _interopDefault(require('shallowequal'));
var levenshtein = _interopDefault(require('fast-levenshtein'));
var ReactDOM = _interopDefault(require('react-dom'));
var PropTypes = _interopDefault(require('prop-types'));
var defaultPolyfill = require('react-lifecycles-compat');
var defaultPolyfill__default = _interopDefault(defaultPolyfill);
var hoistNonReactStatic = _interopDefault(require('hoist-non-react-statics'));
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
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 inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
/* eslint-disable no-underscore-dangle */
var isCompositeComponent = function isCompositeComponent(type) {
return typeof type === 'function';
};
var isReloadableComponent = function isReloadableComponent(type) {
return typeof type === 'function' || (typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object';
};
var getComponentDisplayName = function getComponentDisplayName(type) {
var displayName = type.displayName || type.name;
return displayName && displayName !== 'ReactComponent' ? displayName : 'Component';
};
var reactLifeCycleMountMethods = ['componentWillMount', 'componentDidMount'];
function isReactClass(Component) {
return !!(Component.prototype && (React__default.Component.prototype.isPrototypeOf(Component.prototype) ||
// react 14 support
Component.prototype.isReactComponent || Component.prototype.componentWillMount || Component.prototype.componentWillUnmount || Component.prototype.componentDidMount || Component.prototype.componentDidUnmount || Component.prototype.render));
}
function isReactClassInstance(Component) {
return Component && isReactClass({ prototype: Object.getPrototypeOf(Component) });
}
var getInternalInstance = function getInternalInstance(instance) {
return instance._reactInternalFiber || // React 16
instance._reactInternalInstance || // React 15
null;
};
var updateInstance = function updateInstance(instance) {
var updater = instance.updater,
forceUpdate = instance.forceUpdate;
if (typeof forceUpdate === 'function') {
instance.forceUpdate();
} else if (updater && typeof updater.enqueueForceUpdate === 'function') {
updater.enqueueForceUpdate(instance);
}
};
var isFragmentNode = function isFragmentNode(_ref) {
var type = _ref.type;
return React__default.Fragment && type === React__default.Fragment;
};
var ContextType = React__default.createContext ? React__default.createContext() : null;
var ConsumerType = ContextType && ContextType.Consumer.$$typeof;
var ProviderType = ContextType && ContextType.Provider.$$typeof;
var MemoType = React__default.memo && React__default.memo(function () {
return null;
}).$$typeof;
var LazyType = React__default.lazy && React__default.lazy(function () {
return null;
}).$$typeof;
var ForwardType = React__default.forwardRef && React__default.forwardRef(function () {
return null;
}).$$typeof;
var CONTEXT_CURRENT_VALUE = '_currentValue';
var isContextConsumer = function isContextConsumer(_ref2) {
var type = _ref2.type;
return type && (typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object' && '$$typeof' in type && type.$$typeof === ConsumerType && ConsumerType;
};
var isContextProvider = function isContextProvider(_ref3) {
var type = _ref3.type;
return type && (typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object' && '$$typeof' in type && type.$$typeof === ProviderType && ProviderType;
};
var isMemoType = function isMemoType(_ref4) {
var type = _ref4.type;
return type && (typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object' && '$$typeof' in type && type.$$typeof === MemoType && MemoType;
};
var isLazyType = function isLazyType(_ref5) {
var type = _ref5.type;
return type && (typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object' && '$$typeof' in type && type.$$typeof === LazyType && LazyType;
};
var isForwardType = function isForwardType(_ref6) {
var type = _ref6.type;
return type && (typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object' && '$$typeof' in type && type.$$typeof === ForwardType && ForwardType;
};
var isContextType = function isContextType(type) {
return isContextConsumer(type) || isContextProvider(type);
};
var getElementType = function getElementType(type) {
var element = { type: type };
if (isContextConsumer(element)) {
return 'Consumer';
}
if (isContextProvider(element)) {
return 'Provider';
}
if (isLazyType(element)) {
return 'Lazy';
}
if (isMemoType(element)) {
return 'Memo';
}
if (isForwardType(element)) {
return 'Forward';
}
if (isReactClass(type)) {
return 'Class';
}
if (typeof element === 'function') {
return 'FC';
}
return 'unknown';
};
var getContextProvider = function getContextProvider(type) {
return type && type._context;
};
var configuration = {
// Log level
logLevel: 'error',
// Allows using SFC without changes
pureSFC: true,
// keep render method unpatched, moving sideEffect to componentDidUpdate
pureRender: true,
// Allows SFC to be used, enables "intermediate" components used by Relay, should be disabled for Preact
allowSFC: true,
// Allow reload of effect hooks with non zero dependency list
reloadHooks: true,
// Allow reload of mount effect hooks - zero deps
reloadLifeCycleHooks: false,
// Enables hook reload on hook body change
reloadHooksOnBodyChange: true,
// Disable "hot-replacement-render"
disableHotRenderer: false,
// @private
integratedComparator: false,
// @private
integratedResolver: false,
// Disable "hot-replacement-render" when injection into react-dom is made
disableHotRendererWhenInjected: true,
// Controls `react-🔥-dom patch` notification
showReactDomPatchNotification: true,
// Hook on babel component register.
onComponentRegister: false,
// Hook on React renders for a first time component
onComponentCreate: false,
// flag to completely disable RHL for SFC. Probably don't use it without dom patch made.
ignoreSFC: false,
// ignoreSFC when injection into react-dom is made
ignoreSFCWhenInjected: true,
// flag to completely disable RHL for Components
ignoreComponents: false,
// default value for AppContainer errorOverlay
errorReporter: undefined,
// Global error overlay
ErrorOverlay: undefined,
// Actively track lazy loaded components
trackTailUpdates: true,
// wrap lazy with AppProvider to allow independent updates
wrapLazy: true,
// react hot dom features enabled
IS_REACT_MERGE_ENABLED: false
};
var internalConfiguration = {
// control proxy creation
disableProxyCreation: false
};
var setConfiguration = function setConfiguration(config) {
// not using Object.assing for IE11 compliance
for (var i in config) {
if (config.hasOwnProperty(i)) {
configuration[i] = config[i];
}
}
};
/* eslint-disable no-console */
var logger = {
debug: function debug() {
if (['debug'].indexOf(configuration.logLevel) !== -1) {
var _console;
(_console = console).debug.apply(_console, arguments);
}
},
log: function log() {
if (['debug', 'log'].indexOf(configuration.logLevel) !== -1) {
var _console2;
(_console2 = console).log.apply(_console2, arguments);
}
},
warn: function warn() {
if (['debug', 'log', 'warn'].indexOf(configuration.logLevel) !== -1) {
var _console3;
(_console3 = console).warn.apply(_console3, arguments);
}
},
error: function error() {
if (['debug', 'log', 'warn', 'error'].indexOf(configuration.logLevel) !== -1) {
var _console4;
(_console4 = console).error.apply(_console4, arguments);
}
}
};
/* eslint-disable no-eval, func-names */
function safeReactConstructor(Component, lastInstance) {
try {
if (lastInstance) {
return new Component(lastInstance.props, lastInstance.context);
}
return new Component({}, {});
} catch (e) {
// some components, like Redux connect could not be created without proper context
}
return null;
}
function isNativeFunction(fn) {
return typeof fn === 'function' ? fn.toString().indexOf('[native code]') > 0 : false;
}
var identity = function identity(a) {
return a;
};
var indirectEval = eval;
var doesSupportClasses = function () {
try {
indirectEval('class Test {}');
return true;
} catch (e) {
return false;
}
}();
var ES6ProxyComponentFactory = function ES6ProxyComponentFactory(InitialParent, postConstructionAction) {
return indirectEval('\n(function(InitialParent, postConstructionAction) {\n return class ' + (InitialParent.name || 'HotComponent') + ' extends InitialParent {\n /*\n ! THIS IS NOT YOUR COMPONENT !\n ! THIS IS REACT-HOT-LOADER !\n \n this is a "' + InitialParent.name + '" component, patched by React-Hot-Loader\n Sorry, but the real class code was hidden behind this facade\n Please refer to https://github.com/gaearon/react-hot-loader for details...\n */ \n \n constructor(props, context) {\n super(props, context)\n postConstructionAction.call(this)\n }\n }\n})\n')(InitialParent, postConstructionAction);
};
var ES5ProxyComponentFactory = function ES5ProxyComponentFactory(InitialParent, postConstructionAction) {
function ProxyComponent(props, context) {
InitialParent.call(this, props, context);
postConstructionAction.call(this);
}
ProxyComponent.prototype = Object.create(InitialParent.prototype);
Object.setPrototypeOf(ProxyComponent, InitialParent);
return ProxyComponent;
};
var proxyClassCreator = doesSupportClasses ? ES6ProxyComponentFactory : ES5ProxyComponentFactory;
function getOwnKeys(target) {
return [].concat(Object.getOwnPropertyNames(target), Object.getOwnPropertySymbols(target));
}
function shallowStringsEqual(a, b) {
for (var key in a) {
if (String(a[key]) !== String(b[key])) {
return false;
}
}
return true;
}
function deepPrototypeUpdate(dest, source) {
var deepDest = Object.getPrototypeOf(dest);
var deepSrc = Object.getPrototypeOf(source);
if (deepDest && deepSrc && deepSrc !== deepDest) {
deepPrototypeUpdate(deepDest, deepSrc);
}
if (source.prototype && source.prototype !== dest.prototype) {
dest.prototype = source.prototype;
}
}
function safeDefineProperty(target, key, props) {
try {
Object.defineProperty(target, key, props);
} catch (e) {
logger.warn('Error while wrapping', key, ' -> ', e);
}
}
var PREFIX = '__reactstandin__';
var PROXY_KEY = PREFIX + 'key';
var GENERATION = PREFIX + 'proxyGeneration';
var REGENERATE_METHOD = PREFIX + 'regenerateByEval';
var UNWRAP_PROXY = PREFIX + 'getCurrent';
var CACHED_RESULT = PREFIX + 'cachedResult';
var PROXY_IS_MOUNTED = PREFIX + 'isMounted';
var RENDERED_GENERATION = 'REACT_HOT_LOADER_RENDERED_GENERATION';
var RESERVED_STATICS = ['length', 'displayName', 'name', 'arguments', 'caller', 'prototype', 'toString', 'valueOf', 'isStatelessFunctionalProxy', PROXY_KEY, UNWRAP_PROXY];
function transferStaticProps(ProxyComponent, savedDescriptors, PreviousComponent, NextComponent) {
Object.getOwnPropertyNames(ProxyComponent).forEach(function (key) {
if (RESERVED_STATICS.indexOf(key) !== -1) {
return;
}
var prevDescriptor = Object.getOwnPropertyDescriptor(ProxyComponent, key);
var savedDescriptor = savedDescriptors[key];
if (!shallowEqual(prevDescriptor, savedDescriptor)) {
safeDefineProperty(NextComponent, key, prevDescriptor);
}
});
// Copy newly defined static methods and properties
Object.getOwnPropertyNames(NextComponent).forEach(function (key) {
if (RESERVED_STATICS.indexOf(key) !== -1) {
return;
}
var prevDescriptor = PreviousComponent && Object.getOwnPropertyDescriptor(ProxyComponent, key);
var savedDescriptor = savedDescriptors[key];
// Skip redefined descriptors
if (prevDescriptor && savedDescriptor && !shallowEqual(savedDescriptor, prevDescriptor)) {
safeDefineProperty(NextComponent, key, prevDescriptor);
return;
}
if (prevDescriptor && !savedDescriptor) {
safeDefineProperty(ProxyComponent, key, prevDescriptor);
return;
}
var nextDescriptor = _extends({}, Object.getOwnPropertyDescriptor(NextComponent, key), {
configurable: true
});
savedDescriptors[key] = nextDescriptor;
safeDefineProperty(ProxyComponent, key, nextDescriptor);
});
// Remove static methods and properties that are no longer defined
Object.getOwnPropertyNames(ProxyComponent).forEach(function (key) {
if (RESERVED_STATICS.indexOf(key) !== -1) {
return;
}
// Skip statics that exist on the next class
if (NextComponent.hasOwnProperty(key)) {
return;
}
// Skip non-configurable statics
var proxyDescriptor = Object.getOwnPropertyDescriptor(ProxyComponent, key);
if (proxyDescriptor && !proxyDescriptor.configurable) {
return;
}
var prevDescriptor = PreviousComponent && Object.getOwnPropertyDescriptor(PreviousComponent, key);
var savedDescriptor = savedDescriptors[key];
// Skip redefined descriptors
if (prevDescriptor && savedDescriptor && !shallowEqual(savedDescriptor, prevDescriptor)) {
return;
}
safeDefineProperty(ProxyComponent, key, {
value: undefined
});
});
return savedDescriptors;
}
function mergeComponents(ProxyComponent, NextComponent, InitialComponent, lastInstance, injectedMembers) {
var injectedCode = {};
try {
var nextInstance = safeReactConstructor(NextComponent, lastInstance);
try {
// Bypass babel class inheritance checking
deepPrototypeUpdate(InitialComponent, NextComponent);
} catch (e) {
// It was ES6 class
}
var proxyInstance = safeReactConstructor(ProxyComponent, lastInstance);
if (!nextInstance || !proxyInstance) {
return injectedCode;
}
var mergedAttrs = _extends({}, proxyInstance, nextInstance);
var hasRegenerate = proxyInstance[REGENERATE_METHOD];
var ownKeys = getOwnKeys(Object.getPrototypeOf(ProxyComponent.prototype));
Object.keys(mergedAttrs).forEach(function (key) {
if (key.indexOf(PREFIX) === 0) return;
var nextAttr = nextInstance[key];
var prevAttr = proxyInstance[key];
if (nextAttr) {
if (isNativeFunction(nextAttr) || isNativeFunction(prevAttr)) {
// this is bound method
var isSameArity = nextAttr.length === prevAttr.length;
var existsInPrototype = ownKeys.indexOf(key) >= 0 || ProxyComponent.prototype[key];
if ((isSameArity || !prevAttr) && existsInPrototype) {
if (hasRegenerate) {
injectedCode[key] = 'Object.getPrototypeOf(this)[\'' + key + '\'].bind(this)';
} else {
logger.warn('React Hot Loader:,', 'Non-controlled class', ProxyComponent.name, 'contains a new native or bound function ', key, nextAttr, '. Unable to reproduce');
}
} else {
logger.warn('React Hot Loader:', 'Updated class ', ProxyComponent.name, 'contains native or bound function ', key, nextAttr, '. Unable to reproduce, use arrow functions instead.', '(arity: ' + nextAttr.length + '/' + prevAttr.length + ', proto: ' + (existsInPrototype ? 'yes' : 'no'));
}
return;
}
var nextString = String(nextAttr);
var injectedBefore = injectedMembers[key];
var isArrow = nextString.indexOf('=>') >= 0;
var isFunction = nextString.indexOf('function') >= 0 || isArrow;
var referToThis = nextString.indexOf('this') >= 0;
if (nextString !== String(prevAttr) || injectedBefore && nextString !== String(injectedBefore) || isArrow && referToThis) {
if (!hasRegenerate) {
if (!isFunction) {
// just copy prop over
injectedCode[key] = nextAttr;
} else {
logger.warn('React Hot Loader:', ' Updated class ', ProxyComponent.name, 'had different code for', key, nextAttr, '. Unable to reproduce. Regeneration support needed.');
}
} else {
injectedCode[key] = nextAttr;
}
}
}
});
} catch (e) {
logger.warn('React Hot Loader:', e);
}
return injectedCode;
}
function checkLifeCycleMethods(ProxyComponent, NextComponent) {
try {
var p1 = Object.getPrototypeOf(ProxyComponent.prototype);
var p2 = NextComponent.prototype;
reactLifeCycleMountMethods.forEach(function (key) {
var d1 = Object.getOwnPropertyDescriptor(p1, key) || { value: p1[key] };
var d2 = Object.getOwnPropertyDescriptor(p2, key) || { value: p2[key] };
if (!shallowStringsEqual(d1, d2)) {
logger.warn('React Hot Loader:', 'You did update', ProxyComponent.name, 's lifecycle method', key, '. Unable to repeat');
}
});
} catch (e) {
// Ignore errors
}
}
function inject(target, currentGeneration, injectedMembers) {
if (target[GENERATION] !== currentGeneration) {
var hasRegenerate = !!target[REGENERATE_METHOD];
Object.keys(injectedMembers).forEach(function (key) {
try {
if (hasRegenerate) {
var usedThis = String(injectedMembers[key]).match(/_this([\d]+)/gi) || [];
target[REGENERATE_METHOD](key, '(function REACT_HOT_LOADER_SANDBOX () {\n var _this = this; // common babel transpile\n ' + usedThis.map(function (name) {
return 'var ' + name + ' = this;';
}) + '\n\n return ' + injectedMembers[key] + ';\n }).call(this)');
} else {
target[key] = injectedMembers[key];
}
} catch (e) {
logger.warn('React Hot Loader: Failed to regenerate method ', key, ' of class ', target);
logger.warn('got error', e);
}
});
target[GENERATION] = currentGeneration;
}
}
var has = Object.prototype.hasOwnProperty;
var proxies = new WeakMap();
var resetClassProxies = function resetClassProxies() {
proxies = new WeakMap();
};
var blackListedClassMembers = ['constructor', 'render', 'componentWillMount', 'componentDidMount', 'componentDidCatch', 'componentWillReceiveProps', 'componentWillUnmount', 'hotComponentRender', 'getInitialState', 'getDefaultProps'];
var defaultRenderOptions = {
componentWillRender: identity,
componentDidUpdate: function componentDidUpdate(result) {
return result;
},
componentDidRender: function componentDidRender(result) {
return result;
}
};
var filteredPrototypeMethods = function filteredPrototypeMethods(Proto) {
return Object.getOwnPropertyNames(Proto).filter(function (prop) {
var descriptor = Object.getOwnPropertyDescriptor(Proto, prop);
return descriptor && prop.indexOf(PREFIX) !== 0 && blackListedClassMembers.indexOf(prop) < 0 && typeof descriptor.value === 'function';
});
};
var defineClassMember = function defineClassMember(Class, methodName, methodBody) {
return safeDefineProperty(Class.prototype, methodName, {
configurable: true,
writable: true,
enumerable: false,
value: methodBody
});
};
var defineClassMembers = function defineClassMembers(Class, methods) {
return Object.keys(methods).forEach(function (methodName) {
return defineClassMember(Class, methodName, methods[methodName]);
});
};
var setSFPFlag = function setSFPFlag(component, flag) {
return safeDefineProperty(component, 'isStatelessFunctionalProxy', {
configurable: false,
writable: false,
enumerable: false,
value: flag
});
};
var copyMethodDescriptors = function copyMethodDescriptors(target, source) {
if (source) {
// it is possible to use `function-double` to construct an ideal clone, but does not make a sence
var keys = Object.getOwnPropertyNames(source);
keys.forEach(function (key) {
return safeDefineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
safeDefineProperty(target, 'toString', {
configurable: true,
writable: false,
enumerable: false,
value: function toString() {
return String(source);
}
});
}
return target;
};
var knownClassComponents = [];
var forEachKnownClass = function forEachKnownClass(cb) {
return knownClassComponents.forEach(cb);
};
function createClassProxy(InitialComponent, proxyKey) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var renderOptions = _extends({}, defaultRenderOptions, options);
var proxyConfig = _extends({}, configuration, options.proxy);
// Prevent double wrapping.
// Given a proxy class, return the existing proxy managing it.
var existingProxy = proxies.get(InitialComponent);
if (existingProxy) {
return existingProxy;
}
var CurrentComponent = void 0;
var savedDescriptors = {};
var injectedMembers = {};
var proxyGeneration = 0;
var classUpdatePostponed = null;
var instancesCount = 0;
var isFunctionalComponent = !isReactClass(InitialComponent);
var lastInstance = null;
function postConstructionAction() {
this[GENERATION] = 0;
lastInstance = this;
// is there is an update pending
if (classUpdatePostponed) {
var callUpdate = classUpdatePostponed;
classUpdatePostponed = null;
callUpdate();
}
// As long we can't override constructor
// every class shall evolve from a base class
inject(this, proxyGeneration, injectedMembers);
}
function proxiedUpdate() {
if (this) {
inject(this, proxyGeneration, injectedMembers);
}
}
function lifeCycleWrapperFactory(wrapperName) {
var sideEffect = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : identity;
return copyMethodDescriptors(function wrappedMethod() {
proxiedUpdate.call(this);
sideEffect(this);
for (var _len = arguments.length, rest = Array(_len), _key = 0; _key < _len; _key++) {
rest[_key] = arguments[_key];
}
return !isFunctionalComponent && CurrentComponent.prototype[wrapperName] && CurrentComponent.prototype[wrapperName].apply(this, rest);
}, InitialComponent.prototype && InitialComponent.prototype[wrapperName]);
}
function methodWrapperFactory(wrapperName, realMethod) {
return copyMethodDescriptors(function wrappedMethod() {
for (var _len2 = arguments.length, rest = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
rest[_key2] = arguments[_key2];
}
return realMethod.apply(this, rest);
}, realMethod);
}
var fakeBasePrototype = function fakeBasePrototype(Proto) {
return filteredPrototypeMethods(Proto).reduce(function (acc, key) {
acc[key] = methodWrapperFactory(key, Proto[key]);
return acc;
}, {});
};
var componentDidMount = lifeCycleWrapperFactory('componentDidMount', function (target) {
target[PROXY_IS_MOUNTED] = true;
target[RENDERED_GENERATION] = get$1();
instancesCount++;
});
var componentDidUpdate = lifeCycleWrapperFactory('componentDidUpdate', renderOptions.componentDidUpdate);
var componentWillUnmount = lifeCycleWrapperFactory('componentWillUnmount', function (target) {
target[PROXY_IS_MOUNTED] = false;
instancesCount--;
});
function hotComponentRender() {
// repeating subrender call to keep RENDERED_GENERATION up to date
renderOptions.componentWillRender(this);
proxiedUpdate.call(this);
var result = void 0;
// We need to use hasOwnProperty here, as the cached result is a React node
// and can be null or some other falsy value.
if (has.call(this, CACHED_RESULT)) {
result = this[CACHED_RESULT];
delete this[CACHED_RESULT];
} else if (isFunctionalComponent) {
result = CurrentComponent(this.props, this.context);
} else {
var renderMethod = CurrentComponent.prototype.render || this.render;
/* eslint-disable no-use-before-define */
if (renderMethod === proxiedRender) {
throw new Error('React-Hot-Loader: you are trying to render Component without .render method');
}
/* eslint-enable */
result = renderMethod.apply(this,
// eslint-disable-next-line prefer-rest-params
arguments);
}
return renderOptions.componentDidRender.call(this, result);
}
function hotComponentUpdate() {
renderOptions.componentWillRender(this);
proxiedUpdate.call(this);
}
function proxiedRender() {
renderOptions.componentWillRender(this);
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return hotComponentRender.call.apply(hotComponentRender, [this].concat(args));
}
var defineProxyMethods = function defineProxyMethods(Proxy) {
var Base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
defineClassMembers(Proxy, _extends({}, fakeBasePrototype(Base), proxyConfig.pureRender ? {} : { render: proxiedRender }, {
hotComponentRender: hotComponentRender,
hotComponentUpdate: hotComponentUpdate,
componentDidMount: componentDidMount,
componentDidUpdate: componentDidUpdate,
componentWillUnmount: componentWillUnmount
}));
};
var _ProxyFacade = void 0;
var ProxyComponent = null;
var proxy = void 0;
if (!isFunctionalComponent) {
// Component
ProxyComponent = proxyClassCreator(InitialComponent, postConstructionAction);
defineProxyMethods(ProxyComponent, InitialComponent.prototype);
knownClassComponents.push(ProxyComponent);
_ProxyFacade = ProxyComponent;
} else if (!proxyConfig.allowSFC) {
proxyConfig.pureRender = false;
// SFC Converted to component. Does not support returning precreated instances from render.
ProxyComponent = proxyClassCreator(React.Component, postConstructionAction);
defineProxyMethods(ProxyComponent);
_ProxyFacade = ProxyComponent;
} else {
// SFC
// This function only gets called for the initial mount. The actual
// rendered component instance will be the return value.
// eslint-disable-next-line func-names
_ProxyFacade = function ProxyFacade(props, context) {
/*
! THIS IS NOT YOUR COMPONENT !
! THIS IS REACT-HOT-LOADER !
And you are probably looking for a function component of yours
It's hidden, but there is a way to fix this - just reconfigure your application a bit
see https://github.com/gaearon/react-hot-loader/issues/1311
*/
var result = CurrentComponent(props, context);
// This is a Relay-style container constructor. We can't do the prototype-
// style wrapping for this as we do elsewhere, so just we just pass it
// through as-is.
if (isReactClassInstance(result)) {
ProxyComponent = null;
// Relay lazily sets statics like getDerivedStateFromProps on initial
// render in lazy construction, so we need to do the same here.
transferStaticProps(_ProxyFacade, savedDescriptors, null, CurrentComponent);
return result;
}
// simple SFC, could continue to be SFC
if (proxyConfig.pureSFC) {
if (!CurrentComponent.contextTypes) {
if (!_ProxyFacade.isStatelessFunctionalProxy) {
setSFPFlag(_ProxyFacade, true);
}
return renderOptions.componentDidRender(result);
}
}
setSFPFlag(_ProxyFacade, false);
proxyConfig.pureRender = false;
// Otherwise, it's a normal functional component. Build the real proxy
// and use it going forward.
ProxyComponent = proxyClassCreator(React.Component, postConstructionAction);
defineProxyMethods(ProxyComponent);
var determinateResult = new ProxyComponent(props, context);
// Cache the initial render result so we don't call the component function
// a second time for the initial render.
determinateResult[CACHED_RESULT] = result;
return determinateResult;
};
}
function get$$1() {
return _ProxyFacade;
}
function getCurrent() {
return CurrentComponent;
}
safeDefineProperty(_ProxyFacade, UNWRAP_PROXY, {
configurable: false,
writable: false,
enumerable: false,
value: getCurrent
});
safeDefineProperty(_ProxyFacade, PROXY_KEY, {
configurable: false,
writable: false,
enumerable: false,
value: proxyKey
});
safeDefineProperty(_ProxyFacade, 'toString', {
configurable: true,
writable: false,
enumerable: false,
value: function toString() {
return String(CurrentComponent);
}
});
function update(NextComponent) {
if (typeof NextComponent !== 'function') {
throw new Error('Expected a constructor.');
}
if (NextComponent === CurrentComponent) {
return false;
}
// Prevent proxy cycles
var existingProxy = proxies.get(NextComponent);
if (existingProxy) {
return false;
}
isFunctionalComponent = !isReactClass(NextComponent);
proxies.set(NextComponent, proxy);
proxyGeneration++;
// Save the next constructor so we call it
var PreviousComponent = CurrentComponent;
CurrentComponent = NextComponent;
// Try to infer displayName
var displayName = getComponentDisplayName(CurrentComponent);
safeDefineProperty(_ProxyFacade, 'displayName', {
configurable: true,
writable: false,
enumerable: true,
value: displayName
});
if (ProxyComponent) {
safeDefineProperty(ProxyComponent, 'name', {
value: displayName
});
}
savedDescriptors = transferStaticProps(_ProxyFacade, savedDescriptors, PreviousComponent, NextComponent);
if (isFunctionalComponent || !ProxyComponent) ; else {
var classHotReplacement = function classHotReplacement() {
checkLifeCycleMethods(ProxyComponent, NextComponent);
if (proxyGeneration > 1) {
getElementCloseHook(ProxyComponent);
filteredPrototypeMethods(ProxyComponent.prototype).forEach(function (methodName) {
if (!has.call(NextComponent.prototype, methodName)) {
delete ProxyComponent.prototype[methodName];
}
});
}
Object.setPrototypeOf(ProxyComponent.prototype, NextComponent.prototype);
defineProxyMethods(ProxyComponent, NextComponent.prototype);
if (proxyGeneration > 1) {
injectedMembers = mergeComponents(ProxyComponent, NextComponent, InitialComponent, lastInstance, injectedMembers);
getElementComparisonHook(ProxyComponent);
}
};
// Was constructed once
if (instancesCount > 0) {
classHotReplacement();
} else {
classUpdatePostponed = classHotReplacement;
}
}
return true;
}
update(InitialComponent);
var dereference = function dereference() {
proxies.delete(InitialComponent);
proxies.delete(_ProxyFacade);
proxies.delete(CurrentComponent);
};
proxy = { get: get$$1, update: update, dereference: dereference, getCurrent: function getCurrent() {
return CurrentComponent;
} };
proxies.set(InitialComponent, proxy);
proxies.set(_ProxyFacade, proxy);
safeDefineProperty(proxy, UNWRAP_PROXY, {
configurable: false,
writable: false,
enumerable: false,
value: getCurrent
});
return proxy;
}
// this counter tracks `register` invocations.
// works good, but code splitting is breaking it
var generation = 1;
// these counters are aimed to mitigate the "first render"
var hotComparisonCounter = 0;
var hotComparisonRuns = 0;
var hotReplacementGeneration = 0;
var nullFunction = function nullFunction() {
return {};
};
// these callbacks would be called on component update
var onHotComparisonOpen = nullFunction;
var onHotComparisonElement = nullFunction;
var onHotComparisonClose = nullFunction;
// inversion of control
var setComparisonHooks = function setComparisonHooks(open, element, close) {
onHotComparisonOpen = open;
onHotComparisonElement = element;
onHotComparisonClose = close;
};
var getElementComparisonHook = function getElementComparisonHook(component) {
return onHotComparisonElement(component);
};
var getElementCloseHook = function getElementCloseHook(component) {
return onHotComparisonClose(component);
};
var hotComparisonOpen = function hotComparisonOpen() {
return hotComparisonCounter > 0 && hotComparisonRuns > 0 && hotReplacementGeneration > 0;
};
var openGeneration = function openGeneration() {
return forEachKnownClass(onHotComparisonElement);
};
var closeGeneration = function closeGeneration() {
return forEachKnownClass(onHotComparisonClose);
};
var incrementHot = function incrementHot() {
if (!hotComparisonCounter) {
openGeneration();
onHotComparisonOpen();
}
hotComparisonCounter++;
};
var decrementHot = function decrementHot() {
hotComparisonCounter--;
if (!hotComparisonCounter) {
closeGeneration();
hotComparisonRuns++;
}
};
// TODO: shall it be called from incrementHotGeneration?
var enterHotUpdate = function enterHotUpdate() {
Promise.resolve(incrementHot()).then(function () {
return setTimeout(decrementHot, 0);
});
};
// TODO: deprecate?
var increment = function increment() {
enterHotUpdate();
return generation++;
};
var get$1 = function get() {
return generation;
};
// These counters tracks HMR generations, and probably should be used instead of the old one
var incrementHotGeneration = function incrementHotGeneration() {
return hotReplacementGeneration++;
};
var getHotGeneration = function getHotGeneration() {
return hotReplacementGeneration;
};
// some `empty` names, React can autoset display name to...
var UNDEFINED_NAMES = {
Unknown: true,
Component: true
};
var areNamesEqual = function areNamesEqual(a, b) {
return a === b || UNDEFINED_NAMES[a] && UNDEFINED_NAMES[b];
};
var isFunctional = function isFunctional(fn) {
return typeof fn === 'function';
};
var getTypeOf = function getTypeOf(type) {
if (isReactClass(type)) return 'ReactComponent';
if (isFunctional(type)) return 'StatelessFunctional';
return 'Fragment'; // ?
};
function clearStringFast(str) {
return str.length < 12 ? str : (' ' + str).slice(1);
}
var haveTextSimilarity = function haveTextSimilarity(a, b) {
return (
// equal or slight changed
a === b || levenshtein.get(clearStringFast(a), clearStringFast(b)) < a.length * 0.2
);
};
var getBaseProto = function getBaseProto(source) {
return source.prototype.hotComponentRender ? Object.getPrototypeOf(source.prototype) : source.prototype;
};
var equalClasses = function equalClasses(a, b) {
var prototypeA = getBaseProto(a);
var prototypeB = getBaseProto(b);
var hits = 0;
var misses = 0;
var comparisons = 0;
Object.getOwnPropertyNames(prototypeA).forEach(function (key) {
var descriptorA = Object.getOwnPropertyDescriptor(prototypeA, key);
var valueA = descriptorA && (descriptorA.value || descriptorA.get || descriptorA.set);
var descriptorB = Object.getOwnPropertyDescriptor(prototypeB, key);
var valueB = descriptorB && (descriptorB.value || descriptorB.get || descriptorB.set);
if (typeof valueA === 'function' && key !== 'constructor') {
comparisons++;
if (haveTextSimilarity(String(valueA), String(valueB))) {
hits++;
} else {
misses++;
if (key === 'render') {
misses++;
}
}
}
});
// allow to add or remove one function
return hits > 0 && misses <= 1 || comparisons === 0;
};
var areSwappable = function areSwappable(a, b) {
// both are registered components and have the same name
if (getIdByType(b) && getIdByType(a) === getIdByType(b)) {
return true;
}
if (getTypeOf(a) !== getTypeOf(b)) {
return false;
}
if (isReactClass(a)) {
return areNamesEqual(getComponentDisplayName(a), getComponentDisplayName(b)) && equalClasses(a, b);
}
if (isFunctional(a)) {
var nameA = getComponentDisplayName(a);
if (!areNamesEqual(nameA, getComponentDisplayName(b))) {
return false;
}
return nameA !== 'Component' || haveTextSimilarity(String(a), String(b));
}
return false;
};
function merge() {
var acc = {};
for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
sources[_key] = arguments[_key];
}
for (var _iterator = sources, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
var source = _ref;
if (source instanceof Array) {
if (!(acc instanceof Array)) {
acc = [];
}
acc = [].concat(acc, source);
} else if (source instanceof Object) {
for (var _iterator2 = Object.keys(source), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _babelHelpers$extends;
var _ref2;
if (_isArray2) {
if (_i2 >= _iterator2.length) break;
_ref2 = _iterator2[_i2++];
} else {
_i2 = _iterator2.next();
if (_i2.done) break;
_ref2 = _i2.value;
}
var key = _ref2;
var value = source[key];
if (value instanceof Object && key in acc) {
value = merge(acc[key], value);
}
acc = _extends({}, acc, (_babelHelpers$extends = {}, _babelHelpers$extends[key] = value, _babelHelpers$extends));
}
}
}
return acc;
}
var signatures = void 0;
var proxiesByID = void 0;
var blackListedProxies = void 0;
var registeredComponents = void 0;
var idsByType = void 0;
var elementCount = 0;
var renderOptions = {};
var componentOptions = void 0;
var generateTypeId = function generateTypeId() {
return 'auto-' + elementCount++;
};
var getIdByType = function getIdByType(type) {
return idsByType.get(type);
};
var isProxyType = function isProxyType(type) {
return type[PROXY_KEY];
};
var getProxyById = function getProxyById(id) {
return proxiesByID[id];
};
var getProxyByType = function getProxyByType(type) {
return getProxyById(getIdByType(type));
};
var registerComponent = function registerComponent(type) {
return registeredComponents.set(type, 1);
};
var isRegisteredComponent = function isRegisteredComponent(type) {
return registeredComponents.has(type);
};
var setStandInOptions = function setStandInOptions(options) {
renderOptions = options;
};
var updateFunctionProxyById = function updateFunctionProxyById(id, type, updater) {
// Remember the ID.
idsByType.set(type, id);
var proxy = proxiesByID[id];
if (!proxy) {
proxiesByID[id] = type;
}
updater(proxiesByID[id], type);
// proxiesByID[id] = type; // keep the first ref
return proxiesByID[id];
};
var updateProxyById = function updateProxyById(id, type) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (!id) {
return null;
}
// Remember the ID.
idsByType.set(type, id);
if (!proxiesByID[id]) {
proxiesByID[id] = createClassProxy(type, id, merge({}, renderOptions, { proxy: componentOptions.get(type) || {} }, options));
} else if (proxiesByID[id].update(type)) {
// proxy could be registered again only in case of HMR
incrementHotGeneration();
}
return proxiesByID[id];
};
var createProxyForType = function createProxyForType(type, options) {
return getProxyByType(type) || updateProxyById(generateTypeId(), type, options);
};
var isColdType = function isColdType(type) {
return blackListedProxies.has(type);
};
var isTypeBlacklisted = function isTypeBlacklisted(type) {
return isColdType(type) || isCompositeComponent(type) && (configuration.ignoreSFC && !isReactClass(type) || configuration.ignoreComponents && isReactClass(type));
};
var blacklistByType = function blacklistByType(type) {
return blackListedProxies.set(type, true);
};
var setComponentOptions = function setComponentOptions(component, options) {
return componentOptions.set(component, options);
};
var addSignature = function addSignature(type, signature) {
return signatures.set(type, signature);
};
var getSignature = function getSignature(type) {
return signatures.get(type);
};
var resetProxies = function resetProxies() {
proxiesByID = {};
idsByType = new WeakMap();
blackListedProxies = new WeakMap();
registeredComponents = new WeakMap();
componentOptions = new WeakMap();
signatures = new WeakMap();
resetClassProxies();
};
resetProxies();
var tune = {
allowSFC: false
};
var preactAdapter = function preactAdapter(instance, resolveType) {
var oldHandler = instance.options.vnode;
setConfiguration(tune);
instance.options.vnode = function (vnode) {
if (vnode.type) {
vnode.type = resolveType(vnode.type);
} else if (vnode.nodeName) {
vnode.nodeName = resolveType(vnode.nodeName);
}
if (oldHandler) {
oldHandler(vnode);
}
};
};
/* global document */
var lastError = [];
var overlayStyle = {
position: 'fixed',
left: 0,
top: 0,
right: 0,
backgroundColor: 'rgba(255,200,200,0.9)',
color: '#000',
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif',
fontSize: '12px',
margin: 0,
padding: '16px',
maxHeight: '50%',
overflow: 'auto',
zIndex: 10000
};
var inlineErrorStyle = {
backgroundColor: '#FEE'
};
var liCounter = {
position: 'absolute',
left: '10px'
};
var listStyle = {};
var EmptyErrorPlaceholder = function EmptyErrorPlaceholder(_ref) {
var component = _ref.component;
return React__default.createElement(
'span',
{ style: inlineErrorStyle, role: 'img', 'aria-label': 'Rect-Hot-Loader Error' },
'\u269B\uFE0F\uD83D\uDD25\uD83E\uDD15 (',
component ? getComponentDisplayName(component.constructor || component) : 'Unknown location',
')',
component && component.retryHotLoaderError && React__default.createElement(
'button',
{ onClick: function onClick() {
return component.retryHotLoaderError();
}, title: 'Retry' },
'\u27F3'
)
);
};
var errorHeader = function errorHeader(component, componentStack) {
if (component || componentStack) {
return React__default.createElement(
'span',
null,
'(',
component ? getComponentDisplayName(component.constructor || component) : 'Unknown location',
component && ', ',
componentStack && componentStack.split('\n').filter(Boolean)[0],
')'
);
}
return null;
};
var mapError = function mapError(_ref2) {
var error = _ref2.error,
errorInfo = _ref2.errorInfo,
component = _ref2.component;
if (!error) {
error = { message: 'undefined error' };
}
return React__default.createElement(
React__default.Fragment,
null,
React__default.createElement(
'p',
{ style: { color: 'red' } },
errorHeader(component, errorInfo && errorInfo.componentStack),
' ',
error.toString ? error.toString() : error && error.message || 'undefined error'
),
errorInfo && errorInfo.componentStack ? React__default.createElement(
'div',
null,
React__default.createElement(
'div',
null,
'Stack trace:'
),
React__default.createElement(
'ul',
{ style: { color: 'red', marginTop: '10px' } },
error.stack.split('\n').slice(1, 2).map(function (line, i) {
return React__default.createElement(
'li',
{ key: String(i) },
line
);
}),
React__default.createElement('hr', null),
errorInfo.componentStack.split('\n').filter(Boolean).map(function (line, i) {
return React__default.createElement(
'li',
{ key: String(i) },
line
);
})
)
) : error.stack && React__default.createElement(
'div',
null,
React__default.createElement(
'div',
null,
'Stack trace:'
),
React__default.createElement(
'ul',
{ style: { color: 'red', marginTop: '10px' } },
error.stack.split('\n').map(function (line, i) {
return React__default.createElement(
'li',
{ key: String(i) },
line
);
})
)
)
);
};
var ErrorOverlay = function (_React$Component) {
inherits(ErrorOverlay, _React$Component);
function ErrorOverlay() {
var _temp, _this, _ret;
classCallCheck(this, ErrorOverlay);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.state = {
visible: true
}, _this.toggle = function () {
return _this.setState({ visible: !_this.state.visible });
}, _this.retry = function () {
return _this.setState(function () {
var errors = _this.props.errors;
enterHotUpdate();
clearExceptions();
errors.map(function (_ref3) {
var component = _ref3.component;
return component;
}).filter(Boolean).filter(function (_ref4) {
var retryHotLoaderError = _ref4.retryHotLoaderError;
return !!retryHotLoaderError;
}).forEach(function (component) {
return component.retryHotLoaderError();
});
return {};
});
}, _temp), possibleConstructorReturn(_this, _ret);
}
ErrorOverlay.prototype.render = function render() {
var errors = this.props.errors;
if (!errors.length) {
return null;
}
var visible = this.state.visible;
return React__default.createElement(
'div',
{ style: overlayStyle },
React__default.createElement(
'h2',
{ style: { margin: 0 } },
'\u269B\uFE0F\uD83D\uDD25\uD83D\uDE2D: hot update was not successful ',
React__default.createElement(
'button',
{ onClick: this.toggle },
visible ? 'collapse' : 'expand'
),
React__default.createElement(
'button',
{ onClick: this.retry },
'Retry'
)
),
visible && React__default.createElement(
'ul',
{ style: listStyle },
errors.map(function (err, i) {
return React__default.createElement(
'li',
{ key: i },
React__default.createElement(
'span',
{ style: liCounter },
'(',
i + 1,
'/',
errors.length,
')'
),
mapError(err)
);
})
)
);
};
return ErrorOverlay;
}(React__default.Component);
var initErrorOverlay = function initErrorOverlay() {
if (typeof document === 'undefined' || !document.body) {
return;
}
var div = document.querySelector('.react-hot-loader-error-overlay');
if (!div) {
div = document.createElement('div');
div.className = 'react-hot-loader-error-overlay';
document.body.appendChild(div);
}
if (lastError.length) {
var Overlay = configuration.ErrorOverlay || ErrorOverlay;
ReactDOM.render(React__default.createElement(Overlay, { errors: lastError }), div);
} else {
div.parentNode.removeChild(div);
}
};
function clearExceptions() {
if (lastError.length) {
lastError = [];
initErrorOverlay();
}
}
function logException(error, errorInfo, component) {
// do not suppress error
/* eslint-disable no-console */
console.error(error);
/* eslint-enable */
lastError.push({ error: error, errorInfo: errorInfo, component: component });
initErrorOverlay();
}
/* eslint-disable no-underscore-dangle */
var hotRenderWithHooks = ReactDOM.hotRenderWithHooks || function (fiber