redux-providers
Version:
Minimalist dependency injection system for redux. Create providers to be injected and used in redux reducers.
55 lines (46 loc) • 2.07 kB
text/typescript
import { Constructable } from "../types/constructable";
import { ReduxProviderModuleOptions, AbstractReduxModule } from "../decorators/module/module.decorator";
import { Resolver } from "../resolver/resolver";
import { InstanceContainer } from "../container/instance-container";
import { METADATA_KEY } from "../constants/metadata.keys";
import { applyMiddleware, createStore, Store } from "redux";
export function createReduxStore<ActionTree>(moduleTarget: Constructable<AbstractReduxModule>) {
/** Verify moduleoptions (1) */
if (!Reflect.hasMetadata(METADATA_KEY.REDUX_PROVIDER_MODULE_OPTIONS, moduleTarget)) {
throw new Error("Are you sure " + moduleTarget.name + " is a module?");
}
/** Verify moduleoptions (2) */
const moduleOptions: ReduxProviderModuleOptions = Reflect.getMetadata(METADATA_KEY.REDUX_PROVIDER_MODULE_OPTIONS, moduleTarget);
if (!moduleOptions) {
throw new Error("Module options of " + moduleTarget.name + "must be defined!");
}
/** Create the instance container and add providers */
let container = new InstanceContainer();
const providerList = moduleOptions.providers || [];
for (let provider of providerList) {
Resolver.resolve(provider, container, moduleTarget.name);
}
/** Creating action tree */
let actionTree: any = {};
for (let action in moduleOptions.actions) {
if (moduleOptions.actions.hasOwnProperty(action)) {
actionTree[action] = Resolver.resolve(moduleOptions.actions[action], container, moduleTarget.name);
}
}
/** Set type for the actiontree to provide autocomplete etc */
const actions: ActionTree = actionTree;
/** Get the initial state */
const initialState = moduleOptions.initialState;
/** Create the store */
let store: Store;
if (moduleOptions.middlewares && moduleOptions.middlewares.length > 0) {
store = createStore(moduleOptions.rootReducer, initialState, applyMiddleware(...moduleOptions.middlewares));
} else {
store = createStore(moduleOptions.rootReducer, initialState);
}
return {
container: container,
reduxActions: actions,
reduxStore: store,
};
}