import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; export interface DataStoreEvent { type: string; payload?: any; } export class DataStore { public state: BehaviorSubject; public events: Observable; private _events: BehaviorSubject; private _dispatcher: BehaviorSubject; public get currentState (): any { return this.state.getValue(); } constructor (private _reducer, initialState) { // Initialize State this.state = new BehaviorSubject(initialState); // Initialize Events this._events = new BehaviorSubject({ type: 'init' }); this.events = this._events.asObservable(); // Initialize Dispatcher this._dispatcher = new BehaviorSubject({type: 'init'}); // Subscribe to dispatcher, update state, emit events this._dispatcher.subscribe( event => this._processDispatchedEvent(event) ); } public update (event: DataStoreEvent): void { return this._dispatcher.next(event); } private _processDispatchedEvent (event: DataStoreEvent) { // Update state based on action this.state.next(this._reducer( this.state.getValue(), event )); this._events.next({ type: event.type, payload: this.currentState}); } }