

/**
 * Public API
 */

export function createProvide(store) {
  return function provide(Component, keys) {
    if (isReactComponent(Component))
      return createAlfaProvidedComponent(store, Component, keys)
    else
      return createAlfaProvidedFunction(store, Component, keys)
  }
}

export function createSubscribe(store) {
  return function subscribe(Component, keys) {
    if (isReactComponent(Component))
      return createAlfaSubscribedComponent(store, Component, keys, 'subscribe')
    else
      throw new Error('alfa.subscribe only accepts ReactComponent.')
  }
}


/**
 * Private functions
 */


function isReactComponent(Component) {
  return Component.prototype && Component.prototype.isReactComponent
}


function createAlfaProvidedFunction(store, WrappedFunction, keys) {
  // Keep the name of the orginal function which makes debugging logs easier
  // to understand.
  var funcName = WrappedFunction.name || 'AlfaProvidedFunction'

  return ({
    [funcName]: function(props, context, updater) {
      // Props passed in directly to constructor has higher priority than keys
      // injected from the store.
      // Note: We can certainly define and get a non-global store instance from 
      // context.  But, the question is - what are the benefits?
      props = Object.assign(store.get(keys), props || {})

      // Call the original function.
      return WrappedFunction(props, context, updater)
    }
  })[funcName]
}

function createAlfaProvidedComponent(store, Component, keys) {
  class AlfaProvidedComponent extends Component {
    constructor(props, context) {
      // Props passed in directly to constructor has higher priority than keys
      // injected from the store.
      props = {
        ...store.get(keys),
        ...props
      }

      // Call the original constructor.
      super(props, context)
    }
  }

  return AlfaProvidedComponent
}


function createAlfaSubscribedComponent(store, Component, keys) {
  class AlfaSubscribedComponent extends Component {
    constructor(props, context) {
      // Call the original constructor.
      super(props, context)

      // State of parent constructor has higher priority than keys injected from
      // the store.
      this.state = {
        ...store.get(keys),
        ...this.state
      }

      if ('function' === typeof this.setState)
        store.subscribe(keys, this.setState)

      return this
    }
  }

  return AlfaSubscribedComponent
}

@@ -1481,32 +1481,39 @@
 omponent(store, 
+Wrapped
 Component, keys)
@@ -1521,89 +1521,243 @@
 %7B%0A  
-class AlfaProvidedComponent extends Component 
+// Keep the name of the orginal component which makes debugging logs easier%0A  // to understand.%0A  var componentName = WrappedComponent.name %7C%7C 'AlfaProvidedComponent'%0A%0A  return (
 %7B%0A    
+%5B
 co
-nstructor(props, context) %7B
+mponentName%5D: function(props) %7B%0A      var _props
 %0A   
@@ -1876,17 +1876,18 @@
     
+if (
 props
- = %7B
+)
 %0A   
@@ -1883,35 +1883,55 @@
 (props)%0A        
-...
+_props = Object.assign(
 store.get(keys),
@@ -1934,144 +1934,134 @@
 ys),
-%0A        ...
+ 
 props
+)
 %0A      
-%7D%0A
+else
 %0A      
-// Call the original constructor.%0A      super(props, context)%0A    %7D%0A  %7D%0A%0A  return AlfaProvidedC
+  _props = store.get(keys)%0A%0A      return createElement(WrappedComponent, _props)%0A    %7D%0A  %7D)%5Bc
 omponent
 %0A%7D%0A%0A
@@ -2048,32 +2048,37 @@
 %7D%0A  %7D)%5Bcomponent
+Name%5D
 %0A%7D%0A%0A%0Afunction cr

Make a wrapper component instead of extending the original one.