Polishing
This commit is contained in:
parent
b04936697f
commit
71cef6dee8
|
@ -5,8 +5,8 @@ import { Types } from './redux-arg/structure';
|
|||
const exampleReducer = {
|
||||
example: Types.reducer({
|
||||
form2: Types.reducer(Types.shape({
|
||||
lowerLevel: Types.number(),
|
||||
lowerLevel2: Types.string(),
|
||||
lowerLevel: Types.number(5),
|
||||
lowerLevel2: Types.string('Blargle'),
|
||||
})),
|
||||
form3: Types.reducer({
|
||||
example2: Types.reducer(Types.shape({
|
||||
|
@ -33,7 +33,7 @@ const store = createStore(
|
|||
compose(window.devToolsExtension ? window.devToolsExtension() : f => f)
|
||||
);
|
||||
|
||||
store.dispatch(test.actionsObject.example.form2.update({ lowerLevel: 'nom' }));
|
||||
store.dispatch(test.actionsObject.example.form2.update({ lowerLevel: 2, lowerLevel2: 'Rawrg' }));
|
||||
store.dispatch(test.actionsObject.example.form2.reset());
|
||||
store.dispatch(test.actionsObject.example.form2.replace({ toast: 'nommyNom' }));
|
||||
store.dispatch(test.actionsObject.example.form2.reset());
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//==============================
|
||||
// Flow imports
|
||||
//==============================
|
||||
import type { StructureType, PrimitiveType, ShapeStructure } from './structure';
|
||||
import type { StructureType, PrimitiveType } from './structure';
|
||||
import type { PartialReducer, Selectors } from './reducers';
|
||||
|
||||
import { combineReducers } from 'redux';
|
||||
|
@ -10,7 +10,7 @@ import { reduce, find } from 'lodash';
|
|||
import { createReducer } from './reducers';
|
||||
import { PROP_TYPES } from './structure';
|
||||
|
||||
export function buildReducers(name: string, structure: ShapeStructure, {
|
||||
export function buildReducers(name: string, structure: any, {
|
||||
baseSelector = state => state,
|
||||
locationString = '',
|
||||
}: {
|
||||
|
@ -18,6 +18,7 @@ export function buildReducers(name: string, structure: ShapeStructure, {
|
|||
locationString: string,
|
||||
} = {}): PartialReducer {
|
||||
|
||||
if (structure === undefined) throw new Error(`The structure must be defined for a reducer! LocationString: ${ locationString }`);
|
||||
//Build up the reducers, actions, and selectors for this level. Due to recursion,
|
||||
//these objects will be assigned to a property in the parent object, or simply
|
||||
//returned to the call site for use in the rest of the application.
|
||||
|
@ -37,7 +38,7 @@ export function buildReducers(name: string, structure: ShapeStructure, {
|
|||
//will be some form of shape (or primitives in the case of arrays). At this point we
|
||||
//are only interested in whether or not the structure contains reducers, as that
|
||||
//has an impact on how we proceed with regards to calls.
|
||||
const { structure: propStructure} = propValue();
|
||||
const { structure: propStructure } = propValue();
|
||||
const containsReducers = !!find(propStructure, v => v().type === PROP_TYPES._reducer);
|
||||
|
||||
//Create the child reducer. Depending on whether or not the current structure level contains
|
||||
|
|
|
@ -64,10 +64,11 @@ export function createObjectReducer(reducerShape: StructureType, {
|
|||
}: ObjectReducerOptions = {}) {
|
||||
return {
|
||||
reducers: createReducer(reducerShape, createReducerBehaviors(DEFAULT_OBJECT_BEHAVIORS, locationString)),
|
||||
actionsObject: createActions(DEFAULT_OBJECT_BEHAVIORS, locationString),
|
||||
actionsObject: createActions(DEFAULT_OBJECT_BEHAVIORS, locationString, {}),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function calculateDefaults(reducerStructure) {
|
||||
return reduce(reducerStructure, (memo, propValue, propName) => ({
|
||||
...memo,
|
||||
|
@ -75,29 +76,32 @@ function calculateDefaults(reducerStructure) {
|
|||
}), {});
|
||||
}
|
||||
|
||||
|
||||
function createReducer(objectStructure: StructureType, behaviors: ObjectReducerBehaviors): ObjectReducer {
|
||||
const initialState = calculateDefaults(objectStructure().structure);
|
||||
return (state = initialState, { type, payload }: ObjectReducerAction) => {
|
||||
//If the action type does not match any of the specified behaviors, just return the current state.
|
||||
if (!behaviors[type]) return state;
|
||||
//Sanitize the payload using the reducer shape, then
|
||||
//apply the sanitized payload to the state using the behavior linked to this action type.
|
||||
//TODO: Add validation to payload
|
||||
|
||||
//Sanitize the payload using the reducer shape, then apply the sanitized
|
||||
//payload to the state using the behavior linked to this action type.
|
||||
return behaviors[type](state, validateObject(objectStructure, payload), initialState);
|
||||
}
|
||||
}
|
||||
|
||||
function createActions(behaviorsConfig: ObjectReducerBehaviorsConfig, locationString: string): ObjectActions {
|
||||
|
||||
function createActions(behaviorsConfig: ObjectReducerBehaviorsConfig, locationString: string, defaultPayload: any): ObjectActions {
|
||||
//Take a reducer behavior config object, and create actions using the location string
|
||||
return reduce(behaviorsConfig, (memo, behavior, name) => ({
|
||||
...memo,
|
||||
[name]: (value: Object) => ({
|
||||
type: `${locationString}.${name}`,
|
||||
payload: (behavior.action || (() => {}))(value) || {}
|
||||
payload: (behavior.action || (() => defaultPayload))(value) || {}
|
||||
})
|
||||
}), {});
|
||||
}
|
||||
|
||||
|
||||
function createReducerBehaviors(behaviorsConfig: ObjectReducerBehaviorsConfig, locationString: string): ObjectReducerBehaviors {
|
||||
//Take a reducer behavior config object, and create the reducer behaviors using the location string
|
||||
return reduce(behaviorsConfig, (memo, behavior, name) => ({
|
||||
|
|
|
@ -11,12 +11,13 @@ export type StructureType = () => {
|
|||
structure: ShapeStructure | StructureType | PrimitiveType
|
||||
};
|
||||
export type PrimitiveType = () => {
|
||||
type: string,
|
||||
type: $Keys<typeof PROP_TYPES>,
|
||||
defaultValue?: any,
|
||||
typeofValue: string,
|
||||
structure?: PrimitiveType,
|
||||
};
|
||||
export type TypesObject = {
|
||||
[key: string]: CreateArrayType | CreateStringType | CreateNumberType | CreateObjectType;
|
||||
[key: string]: CreateArrayType | CreateStringType | CreateNumberType | CreateObjectType | CreateBooleanType;
|
||||
}
|
||||
|
||||
export type TypesObjectDefaults = {
|
||||
|
@ -26,6 +27,7 @@ export type TypesArrayDefaults = Array<mixed> | Array<TypesObjectDefaults>;
|
|||
|
||||
type CreateStringType = (defaultValue: string) => PrimitiveType;
|
||||
type CreateNumberType = (defaultValue: number) => PrimitiveType;
|
||||
type CreateBooleanType = (defaultValue: boolean) => PrimitiveType;
|
||||
type CreateArrayType = (structure: StructureType | PrimitiveType, defaultValue: TypesArrayDefaults | TypesObjectDefaults) => StructureType;
|
||||
type CreateObjectType = (structure: ShapeStructure, defaultValue: TypesArrayDefaults | TypesObjectDefaults) => StructureType;
|
||||
|
||||
|
@ -45,12 +47,12 @@ export const Types: TypesObject = {
|
|||
string: (defaultValue: string = '') => () => ({
|
||||
type: PROP_TYPES._string,
|
||||
defaultValue,
|
||||
typeofValue: 'string'
|
||||
typeofValue: 'string',
|
||||
}),
|
||||
number: (defaultValue: number = 0) => () => ({
|
||||
type: PROP_TYPES._number,
|
||||
defaultValue,
|
||||
typeofValue: 'number'
|
||||
typeofValue: 'number',
|
||||
}),
|
||||
boolean: (defaultValue: boolean = false) => () => ({
|
||||
type: PROP_TYPES._boolean,
|
||||
|
|
|
@ -21,14 +21,14 @@ export function validateObject(objectStructure: any, value: mixed): Object {
|
|||
//If the value type does not exist in the reducer structure, we don't want to include it in the payload.
|
||||
//Display a console error for the developer, and skip the inclusion of this property in the payload.
|
||||
if (!valueType) {
|
||||
console.error(`The property, ${name}, was not specified in the structure` +
|
||||
console.warn(`The property, ${name}, was not specified in the structure` +
|
||||
' and was stripped out of the payload. Structure: ', objectStructure().structure);
|
||||
return memo;
|
||||
}
|
||||
|
||||
const validatedValue = getTypeValidation(valueType().type)(valueType, value);
|
||||
if (validatedValue === undefined) {
|
||||
console.error(`The property, ${name}, was populated with a type ${ typeof value } which does not` +
|
||||
console.warn(`The property, ${name}, was populated with a type ${ typeof value } which does not` +
|
||||
' match that specified in the reducer configuration. It has been stripped from' +
|
||||
' the payload');
|
||||
return memo;
|
||||
|
|
Loading…
Reference in New Issue