import React, { Component } from "react" import ReactDOM from "react-dom" import { connect, Provider } from "react-redux" import omit from "lodash/omit" const SystemWrapper = (getSystem, ComponentToWrap ) => class extends Component { render() { return } } const RootWrapper = (reduxStore, ComponentToWrap) => class extends Component { render() { return ( ) } } const makeContainer = (getSystem, component, reduxStore) => { const mapStateToProps = function(state, ownProps) { const propsForContainerComponent = Object.assign({}, ownProps, getSystem()) const ori = component.prototype.mapStateToProps || (state => { return {state} }) return ori(state, propsForContainerComponent) } let wrappedWithSystem = SystemWrapper(getSystem, component, reduxStore) let connected = connect( mapStateToProps )(wrappedWithSystem) if(reduxStore) return RootWrapper(reduxStore, connected) return connected } const handleProps = (getSystem, mapping, props, oldProps) => { for (let prop in mapping) { let fn = mapping[prop] if(typeof fn === "function") fn(props[prop], oldProps[prop], getSystem()) } } export const makeMappedContainer = (getSystem, getStore, memGetComponent, getComponents, componentName, mapping) => { return class extends Component { constructor(props, context) { super(props, context) handleProps(getSystem, mapping, props, {}) } componentWillReceiveProps(nextProps) { handleProps(getSystem, mapping, nextProps, this.props) } render() { let cleanProps = omit(this.props, mapping ? Object.keys(mapping) : []) let Comp = memGetComponent(componentName, "root") return } } } export const render = (getSystem, getStore, getComponent, getComponents, domNode) => { let App = (getComponent(getSystem, getStore, getComponents, "App", "root")) ReactDOM.render(( ), domNode) } // Render try/catch wrapper const createClass = component => class extends Component { render() { return component(this.props) } } const Fallback = ({ name }) =>
😱 Could not render { name === "t" ? "this component" : name }, see the console.
const wrapRender = (component) => { const isStateless = component => !(component.prototype && component.prototype.isReactComponent) const target = isStateless(component) ? createClass(component) : component const ori = target.prototype.render target.prototype.render = function render(...args) { try { return ori.apply(this, args) } catch (error) { console.error(error) // eslint-disable-line no-console return } } return target } export const getComponent = (getSystem, getStore, getComponents, componentName, container) => { if(typeof componentName !== "string") throw new TypeError("Need a string, to fetch a component. Was given a " + typeof componentName) let component = getComponents(componentName) if(!component) { getSystem().log.warn("Could not find component", componentName) return null } if(!container) return wrapRender(component) if(container === "root") return makeContainer(getSystem, component, getStore()) // container == truthy return makeContainer(getSystem, wrapRender(component)) }