Repository URL to install this package:
|
Version:
1.0.0 ▾
|
import React from 'react'
import { toComponentName } from '@skava/identifier'
import { isPromise, isFunction } from 'exotic'
import { ALL_INITIALIZERS, toExport } from './deps'
import { AsyncRequire } from './typings'
class LoadableContext<ResolvedType = typeof React.Component> {
asyncRequire: AsyncRequire<ResolvedType>
resolved?: ResolvedType
isLoaded: boolean
error?: Error
constructor(asyncRequire: AsyncRequire<ResolvedType>) {
this.asyncRequire = asyncRequire
this.isLoaded = this.existing !== undefined
}
get componentName(): string {
return toComponentName(this.resolved!) as string
}
get existing(): boolean | undefined {
return ALL_INITIALIZERS.has(this.asyncRequire)
? ALL_INITIALIZERS.get(this.asyncRequire)
: undefined
}
init(): any | Promise<ResolvedType> {
/**
* @note - added this so we can not call `import` right away...
* @todo this needs more testing - it may need more thought
*/
if (
this.resolved === undefined &&
!isPromise(this.asyncRequire) &&
isFunction(this.asyncRequire)
) {
this.asyncRequire = this.asyncRequire()
}
if (this.resolved === undefined && isPromise(this.asyncRequire)) {
return new Promise(resolve =>
(this.asyncRequire as Promise<ResolvedType>)
.then(resolved => {
this.resolved = toExport(resolved)
this.isLoaded = true
ALL_INITIALIZERS.set(this.asyncRequire, this.resolved)
resolve(this.resolved)
})
.catch(asyncError => {
throw asyncError
})
)
} else {
return this.resolved
}
}
async wait() {
return new Promise(resolve => {
const resolved = this.init()
isPromise(resolved) ? resolve(resolved) : resolve(this.resolved)
})
}
}
export { LoadableContext }
export default LoadableContext