import produce from "immer" ; export class PureStore < S , T > { callbacks = [ ] ; rootState : T ; getter : ( s : S ) => T ; root : any ; parent : any ; constructor ( parent , getter , rootState ? ) { this . parent = parent ; this . root = ( parent && parent . root ) || this ; if ( ! parent ) this . rootState = rootState ; this . getter = ( s ) => getter ( parent ? parent . getter ( s ) : s ) ; } getState = ( ) => this . getter ( this . root . rootState ) ; get state ( ) { return this . getState ( ) ; } update = ( updater ) => { const updaterFn = ( updater instanceof Function ) ? updater : e => Object . assign ( e , updater ) ; const oldState = this . root . rootState ; this . root . rootState = produce ( this . root . rootState , s => { updaterFn ( this . getter ( s ) ) ; } ) ; if ( this . root . rootState !== oldState ) { this . root . callbacks . forEach ( callback => callback ( ) ) ; } } ; storeFor = < X > ( getter ) => new PureStore ( this , getter ) ; updaterFor = < X > ( getter ) => this . storeFor ( getter ) . update ; subscribe = callback => { this . root . callbacks . push ( callback ) ; return ( ) => this . root . callbacks . splice ( this . root . callbacks . indexOf ( callback ) , 1 ) ; } ; } export default < S > ( state ) => ( new PureStore ( null , ( s ) => s , state ) ) ;