Skip to content

Commit

Permalink
refactor: extract InternalStateOperations for creation of StateContext
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Whitfeld committed Apr 24, 2018
1 parent 456c6d9 commit 4d6f6b4
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 66 deletions.
8 changes: 5 additions & 3 deletions packages/store/src/internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ export interface ActionHandlerMetaData {
type: string;
}

export type GetStateFn<T> = () => T;
export type SetStateFn<T> = (newState: T) => void;
export type DispatchFn = (actions: any | any[]) => Observable<any>;
export interface InternalStateOperations<T> {
getState(): T;
setState(val: T);
dispatch(actions: any | any[]): Observable<void>;
}

export interface MetaDataModel {
name: string;
Expand Down
28 changes: 4 additions & 24 deletions packages/store/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,11 @@ export class NgxsRootModule {
stateStream.next({ ...cur, ...results.defaults });
}

factory.connectActionHandlers(
() => stateStream.getValue(),
newState => stateStream.next(newState),
actions => store.dispatch(actions),
results.states
);
factory.connectActionHandlers(results.states);

store.dispatch(new InitState()).subscribe(() => {
if (results) {
factory.invokeInit(
() => stateStream.getValue(),
newState => stateStream.next(newState),
actions => store.dispatch(actions),
results.states
);
factory.invokeInit(results.states);
}
});
}
Expand Down Expand Up @@ -83,21 +73,11 @@ export class NgxsFeatureModule {
stateStream.next({ ...cur, ...results.defaults });
}

factory.connectActionHandlers(
() => stateStream.getValue(),
newState => stateStream.next(newState),
actions => store.dispatch(actions),
results.states
);
factory.connectActionHandlers(results.states);

store.dispatch(new UpdateState()).subscribe(() => {
if (results) {
factory.invokeInit(
() => stateStream.getValue(),
newState => stateStream.next(newState),
actions => store.dispatch(actions),
results.states
);
factory.invokeInit(results.states);
}
});
}
Expand Down
66 changes: 27 additions & 39 deletions packages/store/src/state-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ import {
nameToState,
isObject,
StateClass,
GetStateFn,
SetStateFn,
DispatchFn,
InternalStateOperations,
MappedStore
} from './internals';
import { getActionTypeFromInstance, setValue, getValue } from './utils';
import { ofActionDispatched } from './of-action';
import { InternalActions, ActionStatus, ActionContext } from './actions-stream';
import { InternalDispatchedActionResults } from './dispatcher';
import { InternalDispatchedActionResults, InternalDispatcher } from './dispatcher';
import { StateStream } from './state-stream';

/**
* State factory class
Expand All @@ -39,7 +38,9 @@ export class StateFactory {
@SkipSelf()
private _parentFactory: StateFactory,
private _actions: InternalActions,
private _actionResults: InternalDispatchedActionResults
private _actionResults: InternalDispatchedActionResults,
private _stateStream: StateStream,
private _dispatcher: InternalDispatcher
) {}

/**
Expand Down Expand Up @@ -118,18 +119,13 @@ export class StateFactory {
}
}

connectActionHandlers(
getState: GetStateFn<any>,
setState: SetStateFn<any>,
dispatch: DispatchFn,
mappedStores: MappedStore[]
): any {
connectActionHandlers(mappedStores: MappedStore[]): any {
if (this._connected) return;
this._actions
.pipe(
filter((ctx: ActionContext) => ctx.status === ActionStatus.Dispatched),
mergeMap(({ action }) => {
return this.invokeActions(getState, setState, dispatch, this._actions, action).pipe(
return this.invokeActions(this._actions, action).pipe(
map(() => {
return <ActionContext>{ action, status: ActionStatus.Completed };
}),
Expand All @@ -146,20 +142,22 @@ export class StateFactory {
this._connected = true;
}

private get rootStateOperations(): InternalStateOperations<any> {
return {
getState: () => this._stateStream.getValue(),
setState: newState => this._stateStream.next(newState),
dispatch: actions => this._dispatcher.dispatch(actions)
};
}
/**
* Invoke the init function on the states.
*/
invokeInit(
getState: GetStateFn<any>,
setState: SetStateFn<any>,
dispatch: DispatchFn,
stateMetadatas: MappedStore[]
) {
invokeInit(stateMetadatas: MappedStore[]) {
for (const metadata of stateMetadatas) {
const instance: NgxsLifeCycle = metadata.instance;

if (instance.ngxsOnInit) {
const stateContext = this.createStateContext(getState, setState, dispatch, metadata);
const stateContext = this.createStateContext(metadata);

instance.ngxsOnInit(stateContext);
}
Expand All @@ -169,13 +167,7 @@ export class StateFactory {
/**
* Invoke actions on the states.
*/
invokeActions(
getState: GetStateFn<any>,
setState: SetStateFn<any>,
dispatch: DispatchFn,
actions$: InternalActions,
action
) {
invokeActions(actions$: InternalActions, action) {
const results = [];

for (const metadata of this.states) {
Expand All @@ -184,7 +176,7 @@ export class StateFactory {

if (actionMetas) {
for (const actionMeta of actionMetas) {
const stateContext = this.createStateContext(getState, setState, dispatch, metadata);
const stateContext = this.createStateContext(metadata);
let result = metadata.instance[actionMeta.fn](stateContext, action);

if (result instanceof Promise) {
Expand Down Expand Up @@ -214,39 +206,35 @@ export class StateFactory {
/**
* Create the state context
*/
createStateContext(
getState: GetStateFn<any>,
setState: SetStateFn<any>,
dispatch: DispatchFn,
metadata: MappedStore
): StateContext<any> {
createStateContext(metadata: MappedStore): StateContext<any> {
const root = this.rootStateOperations;
return {
getState(): any {
const state = getState();
const state = root.getState();
return getValue(state, metadata.depth);
},
patchState(val: any): void {
if (Array.isArray(val)) {
throw new Error('Patching arrays is not supported.');
}

let state = getState();
let state = root.getState();
const local = getValue(state, metadata.depth);
for (const k in val) {
local[k] = val[k];
}
state = setValue(state, metadata.depth, { ...local });
setState(state);
root.setState(state);
return state;
},
setState(val: any): any {
let state = getState();
let state = root.getState();
state = setValue(state, metadata.depth, val);
setState(state);
root.setState(state);
return state;
},
dispatch(actions: any | any[]): Observable<any> {
return dispatch(actions);
return root.dispatch(actions);
}
};
}
Expand Down

0 comments on commit 4d6f6b4

Please sign in to comment.