import type { Reducer , Store , Unsubscribe } from 'redux' ; import { actionHydrate , isHydrateAction } from '../actions/persist' ; import { freezeState } from '../utils/freezeState' ; import { PersistItem , PersistOptions } from './PersistItem' ; export class PersistManager { protected readonly list : PersistItem [ ] = [ ] ; protected timer ? : NodeJS . Timeout ; protected unsubscrbeStore ! : Unsubscribe ; constructor ( options ) { this . list = options . map ( ( option ) => new PersistItem ( option ) ) ; } init ( store , hydrate ) { this . unsubscrbeStore = store . subscribe ( ( ) => { this . update ( store . getState ( ) ) ; } ) ; return Promise . all ( this . list . map ( ( item ) => item . init ( ) ) ) . then ( ( ) => { hydrate && store . dispatch ( actionHydrate ( this . collect ( ) ) ) ; } ) ; } destroy ( ) { this . unsubscrbeStore ( ) ; } collect ( ) { return this . list . reduce < Record < string , object > > ( ( stateMaps , item ) => { return Object . assign ( stateMaps , item . collect ( ) ) ; } , { } ) ; } combineReducer ( original ) { return ( state = { } , action ) => { if ( isHydrateAction ( action ) ) { return Object . assign ( { } , state , freezeState ( action . payload ) ) ; } return original ( state , action ) ; } ; } protected update ( nextState ) { this . timer && clearTimeout ( this . timer ) ; this . timer = setTimeout ( ( ) => { this . timer = void this . list . forEach ( ( item ) => { item . update ( nextState ) ; } ) ; } , 50 ) ; } }