All files / decorators asyncState.ts

52.5% Statements 21/40
50% Branches 4/8
37.5% Functions 3/8
52.63% Lines 20/38
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73  1x   1x   1x       1x 4x 2x 2x   2x 2x           2x     1x 1x 1x 1x 1x     1x     1x             1x       1x           1x                                          
//tslint:disable-next-line
const Symbol = require('es6-symbol');
import * as React from 'react';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { mountComponent, unmountComponent } from '../models/asyncComponentTracker';
// tslint:disable:no-invalid-this
// tslint:disable:no-function-expression
 
export const asyncState = <T>(target: new (...args: any[]) => T) => {
  function outer(...args) {
    const instance: any = new target(...args);
    const key = instance.props.asyncKey;
 
    Eif (!instance.key) {
      Object.defineProperty(instance, 'key', {
        writable: false,
        value: key
      });
    }
 
    return instance;
  }
 
  outer.prototype = target.prototype;
  const origMount = target.prototype.componentDidMount;
  const origUnmount = target.prototype.componentWillUnmount;
  outer.prototype.componentDidMount = function () {
    Iif (origMount) {
      origMount.apply(this);
    }
    mountComponent(this);
  };
 
  outer.prototype.componentWillUnmount = function () {
    unmountComponent(this);
    if (origUnmount) {
      origUnmount.apply(this);
    }
  };
 
  outer.prototype.updateAsyncState = outer.prototype.updateAsyncState || function (next) {
    this.setState({ asyncState: next });
  };
 
  return <any>outer;
};
 
export type MapAttributes<S, A> = (asyncKey: Symbol) => (store: S) => A;
export type MapActions<S, A> = (asyncKey: Symbol) => (dispatch: Dispatch<S>) => A;
 
export const asyncConnect = <S, P, A>(Component: React.ComponentClass | React.FunctionComponent) =>
  (mapAttributes: MapAttributes<S, P>, mapActions: MapActions<S, A>) => {
    const dummyKey = Symbol();
    const dummyClass = connect(mapAttributes(dummyKey), mapActions(dummyKey))(Component);
 
    // constructor
    function outter(...args) {
      const asyncKey = Symbol();
      const attributesMapper = mapAttributes(asyncKey);
      const actionMapper = mapActions(asyncKey);
      const injected = connect(attributesMapper, actionMapper)(Component);
 
      return new injected(...args);
    }
 
    outter.prototype = dummyClass.prototype;
    outter.contextTypes = dummyClass.contextTypes;
    outter.childContextTypes = dummyClass.childContextTypes;
 
    return outter;
  };