Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
/**
 * @see https://github.com/jamiebuilds/react-loadable/blob/master/src/index.js
 * @see https://hackernoon.com/effective-code-splitting-in-react-a-practical-guide-2195359d5d49
 */
import React from 'react'

/**
 * examples
 */
// const Product = () =>
//   new Promise(resolve => {
//     require.ensure(
//       [],
//       require => resolve(require('../views/pages/Product')),
//       'ProductPage'
//     )
//   })
// const Register = loadable(import('../../views/pages/Register'))

interface AsyncRequire<ResolvedType> extends Function {
  (): Promise<ResolvedType>
}

class AsyncLoader<ResolvedType> {
  asyncRequire: AsyncRequire<ResolvedType>
  resolved: ResolvedType
  promise: Promise<ResolvedType>

  static init() {
    /**
     * @todo pool
     */
    const instance = new AsyncLoader()
    return instance
  }

  setAsyncRequire(asyncRequire: AsyncRequire<ResolvedType>): void {
    this.asyncRequire = asyncRequire
  }

  setResolved = (result: ResolvedType): void => {
    this.resolved = result
  }

  start() {
    if (this.promise === undefined) {
      this.promise = this.asyncRequire()
      this.promise.then(this.setResolved)
    } else {
      console.warn('[Loadable] already started')
    }

    return this.promise
  }

  clear(): void {
    this.asyncRequire = undefined
  }
}

const loadable = asyncRequire => {
  const asyncLoader = AsyncLoader.init().setAsyncRequire(asyncRequire)

  return class AsyncComponent extends React.Component {
    /**
     * @alias asyncBootstrap
     * @alias bootstrap
     * @alias fetchData
     */
    async fetchData() {
      return asyncLoader.start()
    }

    static preload() {
      return asyncLoader.start()
    }

    componentWillMount() {
      asyncLoader.start()
    }
  }
}