UNPKG

reducer-class

Version:

Boilerplate free class-based reducer creator. Built with TypeScript. Works with Redux and NGRX. Has integration with immer.

55 lines (54 loc) 2.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const immer_1 = require("immer"); const constants_1 = require("./constants"); const errors_1 = require("./errors"); const reducer_class_1 = require("./reducer-class"); class ReducerClassHelpers { typeGuardReducerPure(method) { return method.length !== 3; } addImmerIfNeeded(method) { if (this.typeGuardReducerPure(method)) { return method; } return (state, action) => immer_1.produce(state, (draft) => method(state, draft, action)); } getReducerClassMethodsWthActionTypes(instance, keys) { return keys.reduce((accum, methodName) => { const actionTypes = Reflect.getMetadata(constants_1.METADATA_KEY_ACTION, instance, methodName); if (!actionTypes) { throw new errors_1.MetadataActionMissingError(methodName); } const methodBound = instance[methodName].bind(instance); const method = this.addImmerIfNeeded(methodBound); actionTypes.forEach((actionType) => accum.push({ actionType, method, })); return accum; }, []); } mergeReducers(...reducers) { return (state, action) => reducers.reduce((resState, reducer) => reducer(resState, action), state); } getReducerMap(data) { return data.reduce((accum, { method, actionType }) => { let methodToAdd = method; if (accum[actionType]) { methodToAdd = this.mergeReducers(accum[actionType], method); } accum[actionType] = methodToAdd; return accum; }, {}); } getClassInstanceMethodNames(obj) { const proto = Object.getPrototypeOf(obj); if (!(proto instanceof reducer_class_1.ReducerClass)) { return []; } const protoMethodNames = Object.getOwnPropertyNames(proto).filter((name) => name !== 'constructor' && !name.startsWith(constants_1.PREFIX_OMIT_METHOD)); return [...this.getClassInstanceMethodNames(proto), ...protoMethodNames]; } } exports.ReducerClassHelpers = ReducerClassHelpers;