import * as React from "react" ; export type SmartSubscriber = ( oldState , newState ) => void | Promise < void > ; export type SetStateOptions = { /**
     * You run this when you want to perform multiple operations without dispatching changes yet. You have to manually call .inform() when ready
     */ silent ? : boolean ; } ; export abstract class Smart < StateModel = any , Config = any > { public state : StateModel ; public config : Config ; public subscribers : SmartSubscriber [ ] = [ ] ; protected previousState ? : StateModel ; param config setConfig ( config ? ) { if ( ! config ) { config = { } as Config ; } this . config = config ; } /**
     * Write code for initialisation like defining your state and others
     */ async init ( ) { } /**
     * Write code for initialisation like defining your state and others
     */ async destroy ( ) { } static getContext ( ) { throw new Error ( "Please implement the static getContext() method which returns a React context object." ) ; } param newStateModel setState ( newStateModel , options ? ) { if ( this . isDebug ( ) ) { console . log ( `Previous state` , this . state ) ; console . log ( `Next state` , newStateModel ) ; } this . previousState = this . state ; this . state = newStateModel ; if ( options ?. silent ) { } else { this . inform ( ) ; } } /**
     * Informs all subscribers of a new change.
     */ inform ( previousState ? ) { if ( this . isDebug ( ) ) { console . log ( `Dispatching state change event` ) ; } this . subscribers . forEach ( ( subscriber ) => { subscriber ( previousState || this . previousState , this . state ) ; } ) ; } param subscriber protected subscribe ( subscriber ) { if ( this . subscribers . indexOf ( subscriber ) === - 1 ) { this . subscribers . push ( subscriber ) ; } } param subscriber protected unsubscribe ( subscriber ) { this . subscribers = this . subscribers . filter ( ( s ) => s !== subscriber ) ; } param updateStateModel updateState ( updateStateModel , options ? ) { this . setState ( { ... this . state , ... updateStateModel , } , options ) ; } returns isDebug ( ) { return false ; } }