import * as plugins from './smartstate.plugins'; import { Observable, Subject } from 'rxjs'; import { startWith, takeUntil, map } from 'rxjs/operators'; import { StateAction, IActionDef } from './smartstate.classes.stateaction'; export class StatePart { name: TStatePartName; state = new Subject(); stateStore: TStatePayload; constructor(nameArg: TStatePartName) { this.name = nameArg; } /** * gets the state from the state store */ getState(): TStatePayload { return this.stateStore; } /** * sets the stateStore to the new state * @param newStateArg */ setState(newStateArg: TStatePayload) { this.stateStore = newStateArg; this.notifyChange(); } /** * notifies of a change on the state */ notifyChange() { this.state.next(this.stateStore); } /** * selects a state or a substate */ select(selectorFn?: (state: TStatePayload) => T): Observable { if (!selectorFn) { selectorFn = (state: TStatePayload) => (state); } const mapped = this.state.pipe( startWith(this.getState()), map(selectorFn) ); return mapped; } /** * creates an action capable of modifying the state */ createAction( actionDef: IActionDef ): StateAction { return new StateAction(actionDef); } /** * dispatches an action on the statepart level */ async dispatchAction(stateAction: StateAction, actionPayload: T) { const newState = await stateAction.actionDef(this, actionPayload); this.setState(newState); } }