ngrx-handlers
Version:
NgRx Plugin for Generating Actions and Reducer Based on the Handler Map
108 lines • 10.9 kB
JavaScript
import { __rest } from "tslib";
import { createAction, props } from '@ngrx/store';
/**
* Generates a map of action creators and reducer function based on the initial state, source and handler map.
*
* @param initialState An initial state of the reducer function.
* @param source A source of the actions creators.
* @param handlers A map where the keys are action events and the values are case reducers.
* @returns A tuple of action creator map and the reducer function.
*
* @example
* // movies.state.ts
* interface MoviesState {
* movies: Movie[];
* selectedMovieId: number | null;
* searchTerm: string;
* loading: boolean;
* }
*
* const initMoviesState: MoviesState = {
* movies: [],
* selectedMovieId: null,
* searchTerm: '',
* loading: false,
* };
*
* // movies-page.handlers.ts
* const [moviesPageActions, moviesPageReducer] = combineHandlers(initMoviesState, 'moviesPage', {
* updateSelectedMovieId: (state, { selectedMovieId }: { selectedMovieId: number }) => ({
* ...state,
* selectedMovieId,
* }),
* updateSearchTerm: (state, { searchTerm }: { searchTerm: string }) => ({
* ...state,
* searchTerm,
* }),
* });
*
* // movies-effects.handlers.ts
* const [moviesEffectsActions, moviesEffectsReducer] = combineHandlers(
* initMoviesState,
* 'moviesEffects',
* {
* fetchMovies: state => ({ ...state, loading: true }),
* fetchMoviesSuccess: (state, { movies }: { movies: Movie[] }) => ({
* ...state,
* movies,
* loading: false,
* }),
* fetchMoviesError: state => ({ ...state, movies: [], loading: false }),
* },
* );
*
* @see mergeReducers
*/
export function combineHandlers(initialState, source, handlers) {
return [createActions(source, handlers), createReducer(initialState, source, handlers)];
}
/**
* Creates a plain case reducer.
*
* @returns A plain case reducer.
*
* @example
* const [moviesPageActions, moviesPageReducer] = combineHandlers(initMoviesState, 'moviesPage', {
* showCreateMovieDialog: plain(),
* });
*
* @see combineHandlers
*/
export function plain() {
return state => state;
}
/**
* Creates a plain case reducer with the payload.
*
* @returns A plain case reducer with the payload.
*
* @example
* const [moviesPageActions, moviesPageReducer] = combineHandlers(initMoviesState, 'moviesPage', {
* createMovie: withPayload<{ movie: Movie }>(),
* });
*
* @see combineHandlers
*/
export function withPayload() {
return plain();
}
function createActions(source, handlers) {
return Object.keys(handlers).reduce((actionMap, event) => (Object.assign(Object.assign({}, actionMap), { [event]: createAction(toActionType(source, event), props()) })), {});
}
function createReducer(initialState, source, handlers) {
return (state = initialState, action) => {
const { type } = action, payload = __rest(action, ["type"]);
const reducer = source === toSource(type) ? handlers[toEvent(type)] : null;
return reducer ? reducer(state, payload) : state;
};
}
function toActionType(source, event) {
return `[${source}] ${event}`;
}
function toSource(actionType) {
return actionType.slice(1).split(']').shift();
}
function toEvent(actionType) {
return actionType.split('] ').pop();
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3J4LWhhbmRsZXJzL3NyYy9saWIvaGFuZGxlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBeUIsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUd6RTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9ERztBQUNILE1BQU0sVUFBVSxlQUFlLENBQzdCLFlBQW1CLEVBQ25CLE1BQWMsRUFDZCxRQUFrQjtJQUVsQixPQUFPLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsRUFBRSxhQUFhLENBQUMsWUFBWSxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQzFGLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sVUFBVSxLQUFLO0lBQ25CLE9BQU8sS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUM7QUFDeEIsQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxVQUFVLFdBQVc7SUFDekIsT0FBTyxLQUFLLEVBQUUsQ0FBQztBQUNqQixDQUFDO0FBRUQsU0FBUyxhQUFhLENBQ3BCLE1BQWMsRUFDZCxRQUFrQjtJQUVsQixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUNqQyxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLGlDQUNqQixTQUFTLEtBQ1osQ0FBQyxLQUFLLENBQUMsRUFBRSxZQUFZLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQU8sQ0FBQyxJQUNoRSxFQUNGLEVBQWdDLENBQ2pDLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxhQUFhLENBQ3BCLFlBQW1CLEVBQ25CLE1BQWMsRUFDZCxRQUFrQjtJQUVsQixPQUFPLENBQUMsS0FBSyxHQUFHLFlBQVksRUFBRSxNQUFjLEVBQUUsRUFBRTtRQUM5QyxNQUFNLEVBQUUsSUFBSSxLQUFpQixNQUFNLEVBQWxCLE9BQU8sVUFBSyxNQUFNLEVBQTdCLFFBQW9CLENBQVMsQ0FBQztRQUNwQyxNQUFNLE9BQU8sR0FBRyxNQUFNLEtBQUssUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUUzRSxPQUFPLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQ25ELENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLFlBQVksQ0FBQyxNQUFjLEVBQUUsS0FBYTtJQUNqRCxPQUFPLElBQUksTUFBTSxLQUFLLEtBQUssRUFBRSxDQUFDO0FBQ2hDLENBQUM7QUFFRCxTQUFTLFFBQVEsQ0FBQyxVQUFrQjtJQUNsQyxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRyxDQUFDO0FBQ2pELENBQUM7QUFFRCxTQUFTLE9BQU8sQ0FBQyxVQUFrQjtJQUNqQyxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFHLENBQUM7QUFDdkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFjdGlvbiwgQWN0aW9uUmVkdWNlciwgY3JlYXRlQWN0aW9uLCBwcm9wcyB9IGZyb20gJ0BuZ3J4L3N0b3JlJztcbmltcG9ydCB7IEFjdGlvbk1hcCwgQ2FzZVJlZHVjZXIsIEhhbmRsZXJNYXAsIFBsYWluQ2FzZVJlZHVjZXIgfSBmcm9tICcuL21vZGVscyc7XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgbWFwIG9mIGFjdGlvbiBjcmVhdG9ycyBhbmQgcmVkdWNlciBmdW5jdGlvbiBiYXNlZCBvbiB0aGUgaW5pdGlhbCBzdGF0ZSwgc291cmNlIGFuZCBoYW5kbGVyIG1hcC5cbiAqXG4gKiBAcGFyYW0gaW5pdGlhbFN0YXRlIEFuIGluaXRpYWwgc3RhdGUgb2YgdGhlIHJlZHVjZXIgZnVuY3Rpb24uXG4gKiBAcGFyYW0gc291cmNlIEEgc291cmNlIG9mIHRoZSBhY3Rpb25zIGNyZWF0b3JzLlxuICogQHBhcmFtIGhhbmRsZXJzIEEgbWFwIHdoZXJlIHRoZSBrZXlzIGFyZSBhY3Rpb24gZXZlbnRzIGFuZCB0aGUgdmFsdWVzIGFyZSBjYXNlIHJlZHVjZXJzLlxuICogQHJldHVybnMgQSB0dXBsZSBvZiBhY3Rpb24gY3JlYXRvciBtYXAgYW5kIHRoZSByZWR1Y2VyIGZ1bmN0aW9uLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBtb3ZpZXMuc3RhdGUudHNcbiAqIGludGVyZmFjZSBNb3ZpZXNTdGF0ZSB7XG4gKiAgIG1vdmllczogTW92aWVbXTtcbiAqICAgc2VsZWN0ZWRNb3ZpZUlkOiBudW1iZXIgfCBudWxsO1xuICogICBzZWFyY2hUZXJtOiBzdHJpbmc7XG4gKiAgIGxvYWRpbmc6IGJvb2xlYW47XG4gKiB9XG4gKlxuICogY29uc3QgaW5pdE1vdmllc1N0YXRlOiBNb3ZpZXNTdGF0ZSA9IHtcbiAqICAgbW92aWVzOiBbXSxcbiAqICAgc2VsZWN0ZWRNb3ZpZUlkOiBudWxsLFxuICogICBzZWFyY2hUZXJtOiAnJyxcbiAqICAgbG9hZGluZzogZmFsc2UsXG4gKiB9O1xuICpcbiAqIC8vIG1vdmllcy1wYWdlLmhhbmRsZXJzLnRzXG4gKiBjb25zdCBbbW92aWVzUGFnZUFjdGlvbnMsIG1vdmllc1BhZ2VSZWR1Y2VyXSA9IGNvbWJpbmVIYW5kbGVycyhpbml0TW92aWVzU3RhdGUsICdtb3ZpZXNQYWdlJywge1xuICogICB1cGRhdGVTZWxlY3RlZE1vdmllSWQ6IChzdGF0ZSwgeyBzZWxlY3RlZE1vdmllSWQgfTogeyBzZWxlY3RlZE1vdmllSWQ6IG51bWJlciB9KSA9PiAoe1xuICogICAgIC4uLnN0YXRlLFxuICogICAgIHNlbGVjdGVkTW92aWVJZCxcbiAqICAgfSksXG4gKiAgIHVwZGF0ZVNlYXJjaFRlcm06IChzdGF0ZSwgeyBzZWFyY2hUZXJtIH06IHsgc2VhcmNoVGVybTogc3RyaW5nIH0pID0+ICh7XG4gKiAgICAgLi4uc3RhdGUsXG4gKiAgICAgc2VhcmNoVGVybSxcbiAqICAgfSksXG4gKiB9KTtcbiAqXG4gKiAvLyBtb3ZpZXMtZWZmZWN0cy5oYW5kbGVycy50c1xuICogY29uc3QgW21vdmllc0VmZmVjdHNBY3Rpb25zLCBtb3ZpZXNFZmZlY3RzUmVkdWNlcl0gPSBjb21iaW5lSGFuZGxlcnMoXG4gKiAgIGluaXRNb3ZpZXNTdGF0ZSxcbiAqICAgJ21vdmllc0VmZmVjdHMnLFxuICogICB7XG4gKiAgICAgZmV0Y2hNb3ZpZXM6IHN0YXRlID0+ICh7IC4uLnN0YXRlLCBsb2FkaW5nOiB0cnVlIH0pLFxuICogICAgIGZldGNoTW92aWVzU3VjY2VzczogKHN0YXRlLCB7IG1vdmllcyB9OiB7IG1vdmllczogTW92aWVbXSB9KSA9PiAoe1xuICogICAgICAgLi4uc3RhdGUsXG4gKiAgICAgICBtb3ZpZXMsXG4gKiAgICAgICBsb2FkaW5nOiBmYWxzZSxcbiAqICAgICB9KSxcbiAqICAgICBmZXRjaE1vdmllc0Vycm9yOiBzdGF0ZSA9PiAoeyAuLi5zdGF0ZSwgbW92aWVzOiBbXSwgbG9hZGluZzogZmFsc2UgfSksXG4gKiAgIH0sXG4gKiApO1xuICpcbiAqIEBzZWUgbWVyZ2VSZWR1Y2Vyc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY29tYmluZUhhbmRsZXJzPFN0YXRlLCBIYW5kbGVycyBleHRlbmRzIEhhbmRsZXJNYXA8U3RhdGU+PihcbiAgaW5pdGlhbFN0YXRlOiBTdGF0ZSxcbiAgc291cmNlOiBzdHJpbmcsXG4gIGhhbmRsZXJzOiBIYW5kbGVycyxcbik6IFthY3Rpb25zOiBBY3Rpb25NYXA8U3RhdGUsIEhhbmRsZXJzPiwgcmVkdWNlcjogQWN0aW9uUmVkdWNlcjxTdGF0ZT5dIHtcbiAgcmV0dXJuIFtjcmVhdGVBY3Rpb25zKHNvdXJjZSwgaGFuZGxlcnMpLCBjcmVhdGVSZWR1Y2VyKGluaXRpYWxTdGF0ZSwgc291cmNlLCBoYW5kbGVycyldO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBwbGFpbiBjYXNlIHJlZHVjZXIuXG4gKlxuICogQHJldHVybnMgQSBwbGFpbiBjYXNlIHJlZHVjZXIuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IFttb3ZpZXNQYWdlQWN0aW9ucywgbW92aWVzUGFnZVJlZHVjZXJdID0gY29tYmluZUhhbmRsZXJzKGluaXRNb3ZpZXNTdGF0ZSwgJ21vdmllc1BhZ2UnLCB7XG4gKiAgIHNob3dDcmVhdGVNb3ZpZURpYWxvZzogcGxhaW4oKSxcbiAqIH0pO1xuICpcbiAqIEBzZWUgY29tYmluZUhhbmRsZXJzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwbGFpbjxTdGF0ZT4oKTogUGxhaW5DYXNlUmVkdWNlcjxTdGF0ZT4ge1xuICByZXR1cm4gc3RhdGUgPT4gc3RhdGU7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHBsYWluIGNhc2UgcmVkdWNlciB3aXRoIHRoZSBwYXlsb2FkLlxuICpcbiAqIEByZXR1cm5zIEEgcGxhaW4gY2FzZSByZWR1Y2VyIHdpdGggdGhlIHBheWxvYWQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IFttb3ZpZXNQYWdlQWN0aW9ucywgbW92aWVzUGFnZVJlZHVjZXJdID0gY29tYmluZUhhbmRsZXJzKGluaXRNb3ZpZXNTdGF0ZSwgJ21vdmllc1BhZ2UnLCB7XG4gKiAgIGNyZWF0ZU1vdmllOiB3aXRoUGF5bG9hZDx7IG1vdmllOiBNb3ZpZSB9PigpLFxuICogfSk7XG4gKlxuICogQHNlZSBjb21iaW5lSGFuZGxlcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhQYXlsb2FkPFBheWxvYWQ+KCk6IENhc2VSZWR1Y2VyPGFueSwgUGF5bG9hZD4ge1xuICByZXR1cm4gcGxhaW4oKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQWN0aW9uczxTdGF0ZSwgSGFuZGxlcnMgZXh0ZW5kcyBIYW5kbGVyTWFwPFN0YXRlPj4oXG4gIHNvdXJjZTogc3RyaW5nLFxuICBoYW5kbGVyczogSGFuZGxlcnMsXG4pOiBBY3Rpb25NYXA8U3RhdGUsIEhhbmRsZXJzPiB7XG4gIHJldHVybiBPYmplY3Qua2V5cyhoYW5kbGVycykucmVkdWNlKFxuICAgIChhY3Rpb25NYXAsIGV2ZW50KSA9PiAoe1xuICAgICAgLi4uYWN0aW9uTWFwLFxuICAgICAgW2V2ZW50XTogY3JlYXRlQWN0aW9uKHRvQWN0aW9uVHlwZShzb3VyY2UsIGV2ZW50KSwgcHJvcHM8YW55PigpKSxcbiAgICB9KSxcbiAgICB7fSBhcyBBY3Rpb25NYXA8U3RhdGUsIEhhbmRsZXJzPixcbiAgKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlUmVkdWNlcjxTdGF0ZSwgSGFuZGxlcnMgZXh0ZW5kcyBIYW5kbGVyTWFwPFN0YXRlPj4oXG4gIGluaXRpYWxTdGF0ZTogU3RhdGUsXG4gIHNvdXJjZTogc3RyaW5nLFxuICBoYW5kbGVyczogSGFuZGxlcnMsXG4pOiBBY3Rpb25SZWR1Y2VyPFN0YXRlPiB7XG4gIHJldHVybiAoc3RhdGUgPSBpbml0aWFsU3RhdGUsIGFjdGlvbjogQWN0aW9uKSA9PiB7XG4gICAgY29uc3QgeyB0eXBlLCAuLi5wYXlsb2FkIH0gPSBhY3Rpb247XG4gICAgY29uc3QgcmVkdWNlciA9IHNvdXJjZSA9PT0gdG9Tb3VyY2UodHlwZSkgPyBoYW5kbGVyc1t0b0V2ZW50KHR5cGUpXSA6IG51bGw7XG5cbiAgICByZXR1cm4gcmVkdWNlciA/IHJlZHVjZXIoc3RhdGUsIHBheWxvYWQpIDogc3RhdGU7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHRvQWN0aW9uVHlwZShzb3VyY2U6IHN0cmluZywgZXZlbnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgWyR7c291cmNlfV0gJHtldmVudH1gO1xufVxuXG5mdW5jdGlvbiB0b1NvdXJjZShhY3Rpb25UeXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYWN0aW9uVHlwZS5zbGljZSgxKS5zcGxpdCgnXScpLnNoaWZ0KCkhO1xufVxuXG5mdW5jdGlvbiB0b0V2ZW50KGFjdGlvblR5cGU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBhY3Rpb25UeXBlLnNwbGl0KCddICcpLnBvcCgpITtcbn1cbiJdfQ==