import createMappedRegion , { CreateMappedRegionPureReturnValue } from '../createMappedRegion' ; import { RegionOption , ResultFunc , ResultFuncPure , } from '../types' ; interface LoadBy < V , Extend > { ( asyncFunction ) : ( ) => Promise < void > ; < TResult = unknown > ( asyncFunction , reducer ) : ( ) => Promise < void > ; < TParams = void > ( asyncFunction ) : ( params : TParams ) => Promise < void > ; < TParams = void , TResult = unknown > ( asyncFunction , reducer ) : ( params : TParams ) => Promise < void > ; } export interface CreateRegionReturnValue < V > { set : ( resultOrFunc : V | ResultFunc < V > ) => void ; reset : ( ) => void ; load : ( promise : Promise < V > ) => Promise < void > ; loadBy : LoadBy < V , undefined > ; getValue : ( ) => V | undefined ; getLoading : ( ) => boolean ; getError : ( ) => Error | undefined ; getPromise : ( ) => Promise < V > | undefined ; useValue : { ( ) : V | undefined ; < TResult > ( selector ) : TResult ; } ; useLoading : ( ) => boolean ; useError : ( ) => Error | undefined ; useData : { ( fetcher ) : V ; < TResult > ( fetcher , selector ) : TResult ; } ; } export interface CreateRegionPureReturnValue < V > extends Omit < CreateRegionReturnValue < V > , 'set' | 'loadBy' | 'getValue' | 'useValue' > { set : ( resultOrFunc : V | ResultFuncPure < V > ) => void ; loadBy : LoadBy < V , never > ; getValue : ( ) => V ; useValue : { ( ) : V ; < TResult > ( selector ) : TResult ; } ; } function createRegion < V > ( initialValue , option ? ) ; function createRegion < V > ( initialValue , option ? ) ; function createRegion < V > ( initialValue , option ? ) { type Result = CreateRegionReturnValue < V > ; let region ; if ( initialValue !== undefined ) { region = createMappedRegion < 'value' , V > ( initialValue , option ) ; } else { region = createMappedRegion < 'value' , V > ( undefined , option ) as CreateMappedRegionPureReturnValue < 'value' , V > ; } const set = ( resultOrFunc ) => { return region . set ( 'value' , resultOrFunc ) ; } ; const reset = ( ) => { return region . reset ( 'value' ) ; } ; const load = promise => { return region . load ( 'value' , promise ) ; } ; const loadBy = < TParams = void , TResult = unknown > ( asyncFunction , reducer ? ) => { return region . loadBy ( 'value' , asyncFunction , reducer as any ) as any ; } ; const getValue = ( ) => { return region . getValue ( 'value' ) ; } ; const getLoading = ( ) => { return region . getLoading ( 'value' ) ; } ; const getError = ( ) => { return region . getError ( 'value' ) ; } ; const getPromise = ( ) => { return region . getPromise ( 'value' ) ; } ; const useValue = < TResult > ( selector ? ) => { return region . useValue ( 'value' , selector as ( value : V ) => TResult ) ; } ; const useLoading = ( ) => { return region . useLoading ( 'value' ) ; } ; const useError = ( ) => { return region . useError ( 'value' ) ; } ; const useData = < TResult > ( fetcher , selector ? ) => { return region . useData ( 'value' , fetcher , selector as ( value : V ) => TResult ) ; } ; return { set , reset , load , loadBy , getValue , getLoading , getError , getPromise , useValue , useLoading , useError , useData , } ; } export default createRegion ;