bot18
Version:
A high-frequency cryptocurrency trading bot by Zenbot creator @carlos8f
182 lines (139 loc) • 4.44 kB
JavaScript
const PropTypes = require('prop-types');
const isEqualShallow = require('is-equal-shallow');
const VNode = require('./vnode');
const isClassComponent = component => component.isComponent;
const checkPropTypes = (component, props) => {
if (process.env.NODE_ENV !== 'production' && typeof component.propTypes === 'object') {
const name = component.displayName || component.name;
PropTypes.checkPropTypes(component.propTypes, props, 'prop', name);
}
};
const getProps = vnode => Object.assign({}, vnode.component.defaultProps, vnode.props);
const getNextState = vnode => {
if (isClassComponent(vnode.component)) {
return vnode.instance._pendingState || vnode.instance.state;
}
return null;
};
const mount = (vnode, context, onUpdate) => {
const props = getProps(vnode);
checkPropTypes(vnode.component, props);
if (isClassComponent(vnode.component)) {
vnode.createInstance(props);
vnode.instance._onUpdate = onUpdate;
vnode.instance.context = Object.assign(context, vnode.instance.getChildContext());
vnode.instance.componentWillMount();
vnode.children = vnode.instance._render();
} else {
vnode.children = vnode.component(props, context);
}
};
const componentDidMount = vnode => {
if (isClassComponent(vnode.component)) {
vnode.instance.componentDidMount();
if (vnode.ref) {
vnode.ref(vnode.instance);
}
}
};
const shouldComponentUpdate = (vnode, nextProps, nextState) => {
if (isClassComponent(vnode.component)) {
return vnode.instance.shouldComponentUpdate(nextProps, nextState);
}
return !isEqualShallow(vnode.props, nextProps);
};
const componentWillReceiveProps = (vnode, nextProps) => {
vnode.props = nextProps;
if (isClassComponent(vnode.component)) {
vnode.instance.componentWillReceiveProps(nextProps);
}
};
const rerender = (vnode, context) => {
const nextProps = getProps(vnode);
checkPropTypes(vnode.component, nextProps);
if (isClassComponent(vnode.component)) {
vnode.instance._componentWillUpdate(nextProps, getNextState(vnode));
vnode.children = vnode.instance._render();
return;
}
vnode.children = vnode.component(nextProps, context);
};
const componentDidUpdate = vnode => {
if (isClassComponent(vnode.component)) {
vnode.instance._componentDidUpdate();
}
};
const componentWillUnmount = vnode => {
if (isClassComponent(vnode.component)) {
vnode.instance.componentWillUnmount();
}
};
const unmount = vnode => {
if (isClassComponent(vnode.component)) {
componentWillUnmount(vnode);
vnode.instance = null;
}
vnode.children.forEach(childVNode => {
diff(childVNode, null); // eslint-disable-line no-use-before-define
});
if (isClassComponent(vnode.component) && vnode.ref) {
vnode.ref(null);
}
};
const diff = (prevNode, nextNode, onUpdate, context) => {
if (typeof nextNode === 'number') {
if (prevNode instanceof VNode) {
unmount(prevNode);
}
return String(nextNode);
}
if (!nextNode || typeof nextNode === 'boolean') {
if (prevNode instanceof VNode) {
unmount(prevNode);
}
return null;
}
if (typeof nextNode === 'string') {
if (prevNode instanceof VNode) {
unmount(prevNode);
}
return nextNode;
}
let isUpdate = true;
if (!(prevNode instanceof VNode)) {
mount(nextNode, context, onUpdate);
isUpdate = false;
}
if (isUpdate && prevNode.component !== nextNode.component) {
unmount(prevNode);
mount(nextNode, context, onUpdate);
isUpdate = false;
}
const shouldUpdate = isUpdate && shouldComponentUpdate(prevNode, getProps(nextNode), getNextState(prevNode));
const prevChildren = isUpdate ? [].slice.call(prevNode.children) : [];
if (isUpdate && !isEqualShallow(getProps(prevNode), getProps(nextNode))) {
componentWillReceiveProps(prevNode, getProps(nextNode));
}
if (shouldUpdate) {
rerender(prevNode, context);
}
const nextChildren = isUpdate ? prevNode.children : nextNode.children;
const length = Math.max(prevChildren.length, nextChildren.length);
const reconciledChildren = [];
for (let index = 0; index < length; index++) {
const childNode = diff(prevChildren[index], nextChildren[index], onUpdate, context);
reconciledChildren.push(childNode);
}
if (isUpdate) {
prevNode.children = reconciledChildren;
if (shouldUpdate) {
componentDidUpdate(prevNode);
}
} else {
nextNode.children = reconciledChildren;
componentDidMount(nextNode);
}
return isUpdate ? prevNode : nextNode;
};
module.exports = diff;
;