update action generation
This commit is contained in:
parent
eae70135d5
commit
a4d43456d7
14
test/test.ts
14
test/test.ts
@ -30,12 +30,20 @@ tap.test('should create a new StatePart', async () => {
|
|||||||
|
|
||||||
tap.test('should select something', async () => {
|
tap.test('should select something', async () => {
|
||||||
testStatePart
|
testStatePart
|
||||||
.select(state => state.deep)
|
.select(state => state.deep.hi)
|
||||||
.subscribe(substate => {
|
.subscribe(substate => {
|
||||||
console.log(substate);
|
expect(substate).to.equal(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should dispatch a state action', async () => {});
|
tap.test('should dispatch a state action', async () => {
|
||||||
|
const addFavourite = testStatePart.createAction<string>(async (statePart, payload) => {
|
||||||
|
const currentState = statePart.getState();
|
||||||
|
currentState.currentFavorites.push(payload)
|
||||||
|
return currentState;
|
||||||
|
});
|
||||||
|
await testStatePart.dispatchAction(addFavourite, 'my favourite things')
|
||||||
|
expect(testStatePart.getState().currentFavorites).to.include('my favourite things')
|
||||||
|
});
|
||||||
|
|
||||||
tap.start();
|
tap.start();
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
import * as plugins from './smartstate.plugins';
|
import * as plugins from './smartstate.plugins';
|
||||||
|
import { StatePart } from './smartstate.classes.statepart';
|
||||||
|
|
||||||
|
export interface IActionDef<TStateType, TActionPayloadType> {
|
||||||
|
(stateArg: StatePart<any, TStateType>, actionPayload: TActionPayloadType): Promise<TStateType>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* an actionmodifier for the state
|
* an actionmodifier for the state
|
||||||
*/
|
*/
|
||||||
export class StateAction<StatePayload> {
|
export class StateAction<TStateType, TActionPayloadType> {
|
||||||
constructor(public actionDef: (stateArg: StatePayload) => StatePayload) {}
|
constructor(public actionDef: IActionDef<TStateType, TActionPayloadType>) {}
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,21 @@ import * as plugins from './smartstate.plugins';
|
|||||||
import { Observable, Subject } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
import { startWith, takeUntil, map } from 'rxjs/operators';
|
import { startWith, takeUntil, map } from 'rxjs/operators';
|
||||||
|
|
||||||
import { StateAction } from './smartstate.classes.stateaction';
|
import { StateAction, IActionDef } from './smartstate.classes.stateaction';
|
||||||
|
|
||||||
export class StatePart<StatePartNameType, PayloadType> {
|
export class StatePart<TStatePartName, TStatePayload> {
|
||||||
name: StatePartNameType;
|
name: TStatePartName;
|
||||||
state = new Subject<PayloadType>();
|
state = new Subject<TStatePayload>();
|
||||||
stateStore: PayloadType;
|
stateStore: TStatePayload;
|
||||||
|
|
||||||
constructor(nameArg: StatePartNameType) {
|
constructor(nameArg: TStatePartName) {
|
||||||
this.name = nameArg;
|
this.name = nameArg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets the state from the state store
|
* gets the state from the state store
|
||||||
*/
|
*/
|
||||||
getState(): PayloadType {
|
getState(): TStatePayload {
|
||||||
return this.stateStore;
|
return this.stateStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ export class StatePart<StatePartNameType, PayloadType> {
|
|||||||
* sets the stateStore to the new state
|
* sets the stateStore to the new state
|
||||||
* @param newStateArg
|
* @param newStateArg
|
||||||
*/
|
*/
|
||||||
setState(newStateArg: PayloadType) {
|
setState(newStateArg: TStatePayload) {
|
||||||
this.stateStore = newStateArg;
|
this.stateStore = newStateArg;
|
||||||
this.notifyChange();
|
this.notifyChange();
|
||||||
}
|
}
|
||||||
@ -40,9 +40,9 @@ export class StatePart<StatePartNameType, PayloadType> {
|
|||||||
/**
|
/**
|
||||||
* selects a state or a substate
|
* selects a state or a substate
|
||||||
*/
|
*/
|
||||||
select<T = PayloadType>(selectorFn?: (state: PayloadType) => T): Observable<T> {
|
select<T = TStatePayload>(selectorFn?: (state: TStatePayload) => T): Observable<T> {
|
||||||
if (!selectorFn) {
|
if (!selectorFn) {
|
||||||
selectorFn = (state: PayloadType) => <T>(<any>state);
|
selectorFn = (state: TStatePayload) => <T>(<any>state);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapped = this.state.pipe(
|
const mapped = this.state.pipe(
|
||||||
@ -53,11 +53,18 @@ export class StatePart<StatePartNameType, PayloadType> {
|
|||||||
return mapped;
|
return mapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates an action capable of modifying the state
|
||||||
|
*/
|
||||||
|
createAction <TActionPayload>(actionDef: IActionDef<TStatePayload, TActionPayload>): StateAction<TStatePayload, TActionPayload> {
|
||||||
|
return new StateAction(actionDef);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dispatches an action on the statepart level
|
* dispatches an action on the statepart level
|
||||||
*/
|
*/
|
||||||
async dispatch(stateAction: StateAction<PayloadType>) {
|
async dispatchAction<T>(stateAction: StateAction<TStatePayload, T>, actionPayload: T) {
|
||||||
const newState = stateAction.actionDef(this.getState());
|
const newState = await stateAction.actionDef(this, actionPayload);
|
||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user