import { BehaviorStore, IStateUpdater } from './BehaviorStore'; /** * Prostore which uses BehaviorSubject to hold its state. * It mimics the React class component state management. * You can use setState to change part of the state of the store. * * It performs batched asynchronous state updates which means that * two consequent calls to setState will be batched and result * in dispatching only one store update in the next cycle of the event loop. */ export class AsyncBehaviorStore< State extends object > extends BehaviorStore { _queuedUpdates: IStateUpdater[] = []; _queuedTimeout: any = null; constructor(initialState: State) { super(initialState); } /** * Update part of the store state. * * @param stateUpdate - object containing partial state update or updater function. * If the function is provided, it is called with the current state and should return the partial state update */ setState(stateUpdate: IStateUpdater) { this._queuedUpdates.push(stateUpdate); if (!this._queuedTimeout) { this._queuedTimeout = setTimeout(() => this._applyQueuedUpdates(), 0); } } _applyQueuedUpdates() { let newState = this.state; for (let update of this._queuedUpdates) { newState = this._applyStateUpdater(newState, update); } this._queuedTimeout = null; this._queuedUpdates = []; this.state$.next(newState); } }