From 4a345ae6c2a27c1d02aa08c59afbacf186f5400a Mon Sep 17 00:00:00 2001 From: Ben McGraw Date: Mon, 13 Mar 2023 19:35:55 -0700 Subject: [PATCH 1/7] WIP - reduction from first principles, hosted your Principal Princly E-Pal, me! --- src/app/ReactDockableApp.tsx | 38 +++++----- src/app/layout/components/MenuBar.tsx | 2 +- src/app/layout/components/PropertyBar.tsx | 29 ++++++-- src/app/layout/components/StatusBar.tsx | 1 + src/app/state-management/in-memory/reducer.ts | 74 ++++++++++++++++--- .../in-memory/reducers/tools.reducer.ts | 48 ++++++++++++ 6 files changed, 159 insertions(+), 33 deletions(-) create mode 100644 src/app/state-management/in-memory/reducers/tools.reducer.ts diff --git a/src/app/ReactDockableApp.tsx b/src/app/ReactDockableApp.tsx index 5c44c54..b924777 100644 --- a/src/app/ReactDockableApp.tsx +++ b/src/app/ReactDockableApp.tsx @@ -1,4 +1,4 @@ -import React, {useState /*, useReducer*/} from 'react'; +import React, {useState, useReducer} from 'react'; import {createRoot} from 'react-dom/client'; import {PanelState} from 'react-dockable-ts'; @@ -22,7 +22,12 @@ import { import {mapMaker} from './breaditor/documents/MapDocument'; import {textMaker} from './breaditor/documents/TextDocument'; import {spriteMaker} from './breaditor/documents/SpriteDocument'; -import {TOOLS} from './breaditor/tools/constants'; +// import {TOOLS} from './breaditor/tools/constants'; + +import { + breaditorReducer, + getInitialState, +} from './state-management/in-memory/reducer'; import {DocumentInfo, WidgetInfo} from '../../types/global'; @@ -192,6 +197,12 @@ function getDocumentState() { } function App() { + const [state, dispatch] = useReducer(breaditorReducer, getInitialState()); + + if (dispatch == undefined) { + console.info(state); + } + const [panelState, setPanelState] = useState( createInitialPanelState(), ); @@ -225,9 +236,7 @@ function App() { data-testid="breaditor-browser-app" > { - console.log('I am a fake dispatch in ReactDockableApp. Yay.', foo); - }} + dispatch={dispatch} widgets={getCurrentPanels()} hidden={ { @@ -237,11 +246,8 @@ function App() { getMenu={getMenu} /> { - console.log('Another fake dispatch that was passed: ', bar); - }} - tool={TOOLS.Brush} + state={{tool: {activeTool: 0}}} + dispatch={dispatch} view={{}} />
- { - console.log('A fake dispatch that was passed: ', foo); - }} - /> +
- + ); diff --git a/src/app/layout/components/MenuBar.tsx b/src/app/layout/components/MenuBar.tsx index 05b698f..48732ad 100644 --- a/src/app/layout/components/MenuBar.tsx +++ b/src/app/layout/components/MenuBar.tsx @@ -10,7 +10,7 @@ import css from './MenuBar.module.css'; interface MenuBarProps { dispatch: ({}: any) => void; widgets: WidgetInfo[]; - hidden: {}; + hidden: any; getMenu: () => any; } diff --git a/src/app/layout/components/PropertyBar.tsx b/src/app/layout/components/PropertyBar.tsx index b4424c1..25af211 100644 --- a/src/app/layout/components/PropertyBar.tsx +++ b/src/app/layout/components/PropertyBar.tsx @@ -9,18 +9,35 @@ import css from './PropertyBar.module.css'; import * as icons from '../../ui/icons'; +// interface BrushToolState {} + +interface PropertyBarState { + tool: { + activeTool: number; + brush?: any; //BrushToolState; + }; +} + interface PropertyBarProps { dispatch: ({}: any) => void; - state: {}; - tool: {}; - view: {}; + state: PropertyBarState; + view: any; } const PropertyBar: React.FC = (props) => { function getProperties() { - switch (props.tool) { + const {activeTool} = props.state.tool; + const {dispatch, state, view} = props; + + switch (activeTool) { case TOOLS.Brush: - return ; + return ( + + ); /* case TOOLS.Zoom: return ; @@ -77,7 +94,7 @@ interface BrushPropertiesProps { } const BrushProperties: React.FC = (props) => { let brush: BrushToolProps; - if (props.state.brush) { + if (props.state && props.state.brush) { brush = props.state.brush; } else { brush = { diff --git a/src/app/layout/components/StatusBar.tsx b/src/app/layout/components/StatusBar.tsx index 4140d3c..cc90198 100644 --- a/src/app/layout/components/StatusBar.tsx +++ b/src/app/layout/components/StatusBar.tsx @@ -6,6 +6,7 @@ import css from './PropertyBar.module.css'; interface StatusBarProps { initialStatuses: string[]; + dispatch: ({}: any) => void; } let _stateUpdate = (data: any) => { diff --git a/src/app/state-management/in-memory/reducer.ts b/src/app/state-management/in-memory/reducer.ts index 11beb90..79fe03d 100644 --- a/src/app/state-management/in-memory/reducer.ts +++ b/src/app/state-management/in-memory/reducer.ts @@ -1,16 +1,72 @@ +import {toolsReducer} from './reducers/tools.reducer'; + //import documentsReducer from './reducers/documents.reducer.js'; //import workspaceReducer from './reducers/workspace.reducer.js'; -//import toolsReducer from './reducers/tools.reducer.js'; + //import widgetsReducer from './reducers/widgets.reducer.js'; -export default function reducer(state: any, action: any, ...rest: any[]) { - console.log(state, action, rest); - return { - // tools: toolsReducer(state && state.tools, action, ...rest), - // documents: documentsReducer(state && state.documents, action, ...rest), - // workspace: workspaceReducer(state && state.workspace, action, ...rest), - // widgets: widgetsReducer(state && state.widgets, action, ...rest), +type StringToAnyMap = {[key: string]: any}; +type GenericState = StringToAnyMap; +/* +type GenericAction = { + [key: string]: any; + action: string; +}; +*/ + +type GenericAction = any; + +type GenericReducerMap = { + [key: string]: (state: GenericState, action: GenericAction) => GenericState; +}; + +type Reducer = (state: S, action: A) => S; +type GenericReducer = Reducer; //TODO: GenericReducer will die shortly. But for now... + +function createReducer( + initialState: GenericState, + handlers: GenericReducerMap, +): GenericReducer { + return function ( + state = initialState, + action: GenericAction, + ): GenericReducerMap { + if (action && handlers.hasOwnProperty(action.type)) { + return handlers[action.type](state, action); + } + return state; }; } -export {reducer}; +const breaditorReducer = createReducer( + {}, + { + foo: createReducer( + {}, + { + FOO_ACTION: (state: any, action: any) => { + return {...state, a: state.a + action.foo}; + }, + }, + ), + //tools: toolsReducer, + }, +); + +function taco() { + console.info(toolsReducer); +} + +const getInitialState = function () { + return breaditorReducer({}, {action: 'INITIALIZE_STATE'}); +}; + +export type { + StringToAnyMap, + GenericState, + GenericAction, + GenericReducerMap, + Reducer, + GenericReducer, +}; +export {breaditorReducer, getInitialState, createReducer, taco}; diff --git a/src/app/state-management/in-memory/reducers/tools.reducer.ts b/src/app/state-management/in-memory/reducers/tools.reducer.ts new file mode 100644 index 0000000..1a8b06e --- /dev/null +++ b/src/app/state-management/in-memory/reducers/tools.reducer.ts @@ -0,0 +1,48 @@ +/* +import {createReducer, GenericAction, Reducer} from '../reducer'; + +import {TOOLS} from '../../../breaditor/tools/constants'; //TODO: This should be in *THIS* file, right? +// TODO: and should have a concrete union type I think? + +interface ToolState { + activeTool: number; // Tool index, really + tool: any; // how to type this? + a: number; + b: number; +} + +const initialToolState: ToolState = { + activeTool: TOOLS.Brush, + tool: {}, + a: 0, + b: 0, +}; + +interface ToolActionIncA extends GenericAction { + foo: number; + action: 'INC_A'; +} + +interface ToolActionIncB extends GenericAction { + bar: number; + action: 'INC_B'; +} + +type ToolAction = ToolActionIncA | ToolActionIncB; + +const toolsReducer: Reducer = createReducer( + initialToolState, + { + INC_A: (state, action: ToolActionIncA) => { + return {...state, a: state.a + action.foo}; + }, + INC_B: (state, action: ToolActionIncB) => { + return {...state, b: state.b + action.bar}; + }, + }, +); +*/ + +const toolsReducer = {}; + +export {toolsReducer}; From ac3ddb37126e74a78042898bc5888a4753639181 Mon Sep 17 00:00:00 2001 From: Ben McGraw Date: Mon, 13 Mar 2023 19:48:41 -0700 Subject: [PATCH 2/7] no 111111, only 222222 --- src/app/state-management/in-memory/reducer.ts | 4 +++ .../in-memory/reducers/tools.reducer.ts | 32 ++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/app/state-management/in-memory/reducer.ts b/src/app/state-management/in-memory/reducer.ts index 79fe03d..87c7d62 100644 --- a/src/app/state-management/in-memory/reducer.ts +++ b/src/app/state-management/in-memory/reducer.ts @@ -38,6 +38,10 @@ function createReducer( }; } +console.log( + `inside reducer.ts's transpiled form the value of createReducer is ${createReducer}`, +); + const breaditorReducer = createReducer( {}, { diff --git a/src/app/state-management/in-memory/reducers/tools.reducer.ts b/src/app/state-management/in-memory/reducers/tools.reducer.ts index 1a8b06e..4b2d154 100644 --- a/src/app/state-management/in-memory/reducers/tools.reducer.ts +++ b/src/app/state-management/in-memory/reducers/tools.reducer.ts @@ -1,9 +1,15 @@ -/* -import {createReducer, GenericAction, Reducer} from '../reducer'; +import {createReducer /*GenericAction, Reducer*/} from '../reducer'; -import {TOOLS} from '../../../breaditor/tools/constants'; //TODO: This should be in *THIS* file, right? +// import {TOOLS} from '../../../breaditor/tools/constants'; //TODO: This should be in *THIS* file, right? // TODO: and should have a concrete union type I think? +if (createReducer == undefined) { + console.log('222222: My life is a lie.'); +} else { + console.log('222222: The world is like, square, maaaaan.'); +} + +/* interface ToolState { activeTool: number; // Tool index, really tool: any; // how to type this? @@ -30,7 +36,8 @@ interface ToolActionIncB extends GenericAction { type ToolAction = ToolActionIncA | ToolActionIncB; -const toolsReducer: Reducer = createReducer( +/* +let toolsReducer: Reducer = createReducer( initialToolState, { INC_A: (state, action: ToolActionIncA) => { @@ -43,6 +50,21 @@ const toolsReducer: Reducer = createReducer( ); */ +/* +let bar: Reducer; +bar = function (a: any, b: any) { + console.warn(b); + return a; +}; +*/ + +console.log('createReducer is', createReducer); + +// console.log(bar); +// console.log(initialToolState); + +const foo = createReducer({}, {}); + const toolsReducer = {}; -export {toolsReducer}; +export {toolsReducer, foo}; From 7dd40c4893c8892f59b88193a1d4af3bab90253c Mon Sep 17 00:00:00 2001 From: Ben McGraw Date: Mon, 13 Mar 2023 21:52:09 -0700 Subject: [PATCH 3/7] a working typed reducer --- src/app/ReactDockableApp.tsx | 2 +- .../in-memory/main_reducer.ts | 32 ++++++++ .../state-management/in-memory/reducer.inc.ts | 45 +++++++++++ src/app/state-management/in-memory/reducer.ts | 76 ------------------- .../in-memory/reducers/tools.reducer.test.ts | 17 +++++ .../in-memory/reducers/tools.reducer.ts | 59 +++++--------- src/app/state-management/in-memory/store.tsx | 2 +- 7 files changed, 114 insertions(+), 119 deletions(-) create mode 100644 src/app/state-management/in-memory/main_reducer.ts create mode 100644 src/app/state-management/in-memory/reducer.inc.ts delete mode 100644 src/app/state-management/in-memory/reducer.ts create mode 100644 src/app/state-management/in-memory/reducers/tools.reducer.test.ts diff --git a/src/app/ReactDockableApp.tsx b/src/app/ReactDockableApp.tsx index b924777..63b641b 100644 --- a/src/app/ReactDockableApp.tsx +++ b/src/app/ReactDockableApp.tsx @@ -27,7 +27,7 @@ import {spriteMaker} from './breaditor/documents/SpriteDocument'; import { breaditorReducer, getInitialState, -} from './state-management/in-memory/reducer'; +} from './state-management/in-memory/main_reducer'; import {DocumentInfo, WidgetInfo} from '../../types/global'; diff --git a/src/app/state-management/in-memory/main_reducer.ts b/src/app/state-management/in-memory/main_reducer.ts new file mode 100644 index 0000000..7e12500 --- /dev/null +++ b/src/app/state-management/in-memory/main_reducer.ts @@ -0,0 +1,32 @@ +import {createReducer} from './reducer.inc'; +import {toolsReducer} from './reducers/tools.reducer'; + +//import documentsReducer from './reducers/documents.reducer.js'; +//import workspaceReducer from './reducers/workspace.reducer.js'; + +//import widgetsReducer from './reducers/widgets.reducer.js'; + +const breaditorReducer = createReducer( + {}, + { + foo: createReducer( + {}, + { + FOO_ACTION: (state: any, action: any) => { + return {...state, a: state.a + action.foo}; + }, + }, + ), + //tools: toolsReducer, + }, +); + +const taco = function () { + toolsReducer; +}; + +const getInitialState = function () { + return breaditorReducer({}, {action: 'INITIALIZE_STATE'}); +}; + +export {breaditorReducer, getInitialState, createReducer, taco}; diff --git a/src/app/state-management/in-memory/reducer.inc.ts b/src/app/state-management/in-memory/reducer.inc.ts new file mode 100644 index 0000000..f381aec --- /dev/null +++ b/src/app/state-management/in-memory/reducer.inc.ts @@ -0,0 +1,45 @@ +type StringToAnyMap = {[key: string]: any}; +type GenericState = StringToAnyMap; + +// type GenericAction = { +// [key: string]: any; +// type: string; +// }; + +type GenericAction = any; + +type GenericReducerMap = { + [key: string]: (state: GenericState, action: GenericAction) => GenericState; +}; + +type Reducer = (state: S, action: A) => S; +type GenericReducer = Reducer; //TODO: GenericReducer will die shortly. But for now... + +function createReducer( + initialState: GenericState, + handlers: GenericReducerMap, +): GenericReducer { + const myHandlers = handlers; + + return function ( + state = initialState, + action: GenericAction, + ): GenericReducerMap { + if (action && myHandlers.hasOwnProperty(action.type)) { + return myHandlers[action.type](state, action); + } else { + // console.error(`Unhandled action: ${action.type} `); + } + return state; + }; +} + +export type { + StringToAnyMap, + GenericState, + GenericAction, + GenericReducerMap, + Reducer, + GenericReducer, +}; +export {createReducer}; diff --git a/src/app/state-management/in-memory/reducer.ts b/src/app/state-management/in-memory/reducer.ts deleted file mode 100644 index 87c7d62..0000000 --- a/src/app/state-management/in-memory/reducer.ts +++ /dev/null @@ -1,76 +0,0 @@ -import {toolsReducer} from './reducers/tools.reducer'; - -//import documentsReducer from './reducers/documents.reducer.js'; -//import workspaceReducer from './reducers/workspace.reducer.js'; - -//import widgetsReducer from './reducers/widgets.reducer.js'; - -type StringToAnyMap = {[key: string]: any}; -type GenericState = StringToAnyMap; -/* -type GenericAction = { - [key: string]: any; - action: string; -}; -*/ - -type GenericAction = any; - -type GenericReducerMap = { - [key: string]: (state: GenericState, action: GenericAction) => GenericState; -}; - -type Reducer = (state: S, action: A) => S; -type GenericReducer = Reducer; //TODO: GenericReducer will die shortly. But for now... - -function createReducer( - initialState: GenericState, - handlers: GenericReducerMap, -): GenericReducer { - return function ( - state = initialState, - action: GenericAction, - ): GenericReducerMap { - if (action && handlers.hasOwnProperty(action.type)) { - return handlers[action.type](state, action); - } - return state; - }; -} - -console.log( - `inside reducer.ts's transpiled form the value of createReducer is ${createReducer}`, -); - -const breaditorReducer = createReducer( - {}, - { - foo: createReducer( - {}, - { - FOO_ACTION: (state: any, action: any) => { - return {...state, a: state.a + action.foo}; - }, - }, - ), - //tools: toolsReducer, - }, -); - -function taco() { - console.info(toolsReducer); -} - -const getInitialState = function () { - return breaditorReducer({}, {action: 'INITIALIZE_STATE'}); -}; - -export type { - StringToAnyMap, - GenericState, - GenericAction, - GenericReducerMap, - Reducer, - GenericReducer, -}; -export {breaditorReducer, getInitialState, createReducer, taco}; diff --git a/src/app/state-management/in-memory/reducers/tools.reducer.test.ts b/src/app/state-management/in-memory/reducers/tools.reducer.test.ts new file mode 100644 index 0000000..7099908 --- /dev/null +++ b/src/app/state-management/in-memory/reducers/tools.reducer.test.ts @@ -0,0 +1,17 @@ +import { + toolsReducer, + initialToolState, + /*Reducer /*GenericAction, Reducer*/ +} from './tools.reducer'; + +test('toolsReducer INC_A', () => { + const result = toolsReducer(initialToolState, {type: 'INC_A', foo: 2}); + + expect(result.a).toBe(2); +}); + +test('toolsReducer INC_A', () => { + const result = toolsReducer(initialToolState, {type: 'INC_B', bar: 7}); + + expect(result.b).toBe(7); +}); diff --git a/src/app/state-management/in-memory/reducers/tools.reducer.ts b/src/app/state-management/in-memory/reducers/tools.reducer.ts index 4b2d154..8ba152c 100644 --- a/src/app/state-management/in-memory/reducers/tools.reducer.ts +++ b/src/app/state-management/in-memory/reducers/tools.reducer.ts @@ -1,15 +1,11 @@ -import {createReducer /*GenericAction, Reducer*/} from '../reducer'; +import { + createReducer, + Reducer /*GenericAction, Reducer*/, +} from '../reducer.inc'; -// import {TOOLS} from '../../../breaditor/tools/constants'; //TODO: This should be in *THIS* file, right? +import {TOOLS} from '../../../breaditor/tools/constants'; //TODO: This should be in *THIS* file, right? // TODO: and should have a concrete union type I think? -if (createReducer == undefined) { - console.log('222222: My life is a lie.'); -} else { - console.log('222222: The world is like, square, maaaaan.'); -} - -/* interface ToolState { activeTool: number; // Tool index, really tool: any; // how to type this? @@ -17,27 +13,26 @@ interface ToolState { b: number; } -const initialToolState: ToolState = { - activeTool: TOOLS.Brush, - tool: {}, - a: 0, - b: 0, -}; - -interface ToolActionIncA extends GenericAction { +interface ToolActionIncA { foo: number; - action: 'INC_A'; + type: 'INC_A'; } -interface ToolActionIncB extends GenericAction { +interface ToolActionIncB { bar: number; - action: 'INC_B'; + type: 'INC_B'; } type ToolAction = ToolActionIncA | ToolActionIncB; -/* -let toolsReducer: Reducer = createReducer( +const initialToolState: ToolState = { + activeTool: TOOLS.Brush, + tool: {}, + a: 0, + b: 0, +}; + +const toolsReducer: Reducer = createReducer( initialToolState, { INC_A: (state, action: ToolActionIncA) => { @@ -48,23 +43,5 @@ let toolsReducer: Reducer = createReducer( }, }, ); -*/ - -/* -let bar: Reducer; -bar = function (a: any, b: any) { - console.warn(b); - return a; -}; -*/ - -console.log('createReducer is', createReducer); - -// console.log(bar); -// console.log(initialToolState); - -const foo = createReducer({}, {}); - -const toolsReducer = {}; -export {toolsReducer, foo}; +export {initialToolState, toolsReducer}; diff --git a/src/app/state-management/in-memory/store.tsx b/src/app/state-management/in-memory/store.tsx index b86dc85..9486356 100644 --- a/src/app/state-management/in-memory/store.tsx +++ b/src/app/state-management/in-memory/store.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import reducer from './reducer.js'; +import reducer from './main_reducer.js'; class Store { state = reducer(null, {}); // initialize? From 155be0803a33bff271803e624a1a0343dc0ea92e Mon Sep 17 00:00:00 2001 From: Ben McGraw Date: Mon, 13 Mar 2023 21:56:48 -0700 Subject: [PATCH 4/7] Typing Action better... --- src/app/state-management/in-memory/reducer.inc.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/app/state-management/in-memory/reducer.inc.ts b/src/app/state-management/in-memory/reducer.inc.ts index f381aec..96a7390 100644 --- a/src/app/state-management/in-memory/reducer.inc.ts +++ b/src/app/state-management/in-memory/reducer.inc.ts @@ -1,19 +1,17 @@ type StringToAnyMap = {[key: string]: any}; type GenericState = StringToAnyMap; -// type GenericAction = { -// [key: string]: any; -// type: string; -// }; - -type GenericAction = any; +type GenericAction = { + [key: string]: any; + type: string; +}; type GenericReducerMap = { [key: string]: (state: GenericState, action: GenericAction) => GenericState; }; type Reducer = (state: S, action: A) => S; -type GenericReducer = Reducer; //TODO: GenericReducer will die shortly. But for now... +type GenericReducer = Reducer; //TODO: GenericReducer will die shortly. But for now... function createReducer( initialState: GenericState, From 6903362ba3278da50eaccb75630fd6cef3f63fe5 Mon Sep 17 00:00:00 2001 From: Ben McGraw Date: Mon, 13 Mar 2023 22:03:45 -0700 Subject: [PATCH 5/7] remove the extraneous generic states --- .../state-management/in-memory/reducer.inc.ts | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/app/state-management/in-memory/reducer.inc.ts b/src/app/state-management/in-memory/reducer.inc.ts index 96a7390..0f23ef6 100644 --- a/src/app/state-management/in-memory/reducer.inc.ts +++ b/src/app/state-management/in-memory/reducer.inc.ts @@ -6,23 +6,19 @@ type GenericAction = { type: string; }; -type GenericReducerMap = { - [key: string]: (state: GenericState, action: GenericAction) => GenericState; +type ReducerMap = { + [key: string]: (state: S, action: A) => S; }; type Reducer = (state: S, action: A) => S; -type GenericReducer = Reducer; //TODO: GenericReducer will die shortly. But for now... -function createReducer( - initialState: GenericState, - handlers: GenericReducerMap, -): GenericReducer { +function createReducer( + initialState: S, + handlers: ReducerMap, +): Reducer { const myHandlers = handlers; - return function ( - state = initialState, - action: GenericAction, - ): GenericReducerMap { + return function (state: S = initialState, action: A): S { if (action && myHandlers.hasOwnProperty(action.type)) { return myHandlers[action.type](state, action); } else { @@ -32,12 +28,5 @@ function createReducer( }; } -export type { - StringToAnyMap, - GenericState, - GenericAction, - GenericReducerMap, - Reducer, - GenericReducer, -}; +export type {StringToAnyMap, Reducer}; export {createReducer}; From 1052ebd809f003588955885910c370404f26197d Mon Sep 17 00:00:00 2001 From: Ben McGraw Date: Mon, 13 Mar 2023 22:13:36 -0700 Subject: [PATCH 6/7] Dan gets his default initializers --- .../state-management/in-memory/reducer.inc.ts | 21 +++++++++++++------ .../in-memory/reducers/tools.reducer.test.ts | 7 +++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/app/state-management/in-memory/reducer.inc.ts b/src/app/state-management/in-memory/reducer.inc.ts index 0f23ef6..546f124 100644 --- a/src/app/state-management/in-memory/reducer.inc.ts +++ b/src/app/state-management/in-memory/reducer.inc.ts @@ -10,21 +10,30 @@ type ReducerMap = { [key: string]: (state: S, action: A) => S; }; -type Reducer = (state: S, action: A) => S; +type Reducer = (state?: S, action?: A) => S; function createReducer( initialState: S, handlers: ReducerMap, ): Reducer { const myHandlers = handlers; + const myInitialState = initialState; - return function (state: S = initialState, action: A): S { - if (action && myHandlers.hasOwnProperty(action.type)) { - return myHandlers[action.type](state, action); + return function (state?: S, action?: A): S { + if (state == null && action == null) { + return myInitialState; } else { - // console.error(`Unhandled action: ${action.type} `); + if (state != null) { + if (action && myHandlers.hasOwnProperty(action.type)) { + return myHandlers[action.type](state, action); + } else { + // console.error(`Unhandled action: ${action.type} `); + } + return state; + } } - return state; + + throw new Error('This should never happen!'); }; } diff --git a/src/app/state-management/in-memory/reducers/tools.reducer.test.ts b/src/app/state-management/in-memory/reducers/tools.reducer.test.ts index 7099908..77424ce 100644 --- a/src/app/state-management/in-memory/reducers/tools.reducer.test.ts +++ b/src/app/state-management/in-memory/reducers/tools.reducer.test.ts @@ -4,6 +4,13 @@ import { /*Reducer /*GenericAction, Reducer*/ } from './tools.reducer'; +test('toolsReducer INIT', () => { + const result = toolsReducer(); + + expect(result.a).toBe(0); + expect(result.b).toBe(0); +}); + test('toolsReducer INC_A', () => { const result = toolsReducer(initialToolState, {type: 'INC_A', foo: 2}); From 8b020a3307d5a0ba80617b714f858b39fb3614d8 Mon Sep 17 00:00:00 2001 From: Ben McGraw Date: Mon, 13 Mar 2023 22:40:39 -0700 Subject: [PATCH 7/7] Simplify createReducer after talking to Dan --- .../state-management/in-memory/reducer.inc.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/app/state-management/in-memory/reducer.inc.ts b/src/app/state-management/in-memory/reducer.inc.ts index 546f124..ab7509f 100644 --- a/src/app/state-management/in-memory/reducer.inc.ts +++ b/src/app/state-management/in-memory/reducer.inc.ts @@ -19,21 +19,17 @@ function createReducer( const myHandlers = handlers; const myInitialState = initialState; - return function (state?: S, action?: A): S { - if (state == null && action == null) { + return function (state: S = myInitialState, action?: A): S { + if (action == null) { return myInitialState; } else { - if (state != null) { - if (action && myHandlers.hasOwnProperty(action.type)) { - return myHandlers[action.type](state, action); - } else { - // console.error(`Unhandled action: ${action.type} `); - } - return state; + if (action && myHandlers.hasOwnProperty(action.type)) { + return myHandlers[action.type](state, action); + } else { + // console.error(`Unhandled action: ${action.type} `); } + return state; } - - throw new Error('This should never happen!'); }; }