diff --git a/package.json b/package.json index 17170fe..6c017ee 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "react-dom": "^16.7.0", "react-redux": "^6.0.0", "react-scripts": "2.1.3", + "redux-observable": "^1.0.0", + "rxjs": "^6.4.0", "typescript": "3.2.4" }, "scripts": { diff --git a/src/index.tsx b/src/index.tsx index 3d1acfa..a4d840f 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,19 +1,28 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { createStore } from 'redux'; +import { createStore, applyMiddleware } from 'redux'; import { Provider } from 'react-redux'; +import { createEpicMiddleware } from 'redux-observable'; -import { reducers } from './state'; +import { reducers, epics, Action, State } from './state'; import * as WorkloadActions from './state/workloads/actions'; -import { WorkloadService } from './state/workloads/services'; - import './index.css'; import App from './App'; -// demo store +const epicMiddleware = createEpicMiddleware(); +const store = createStore(reducers, applyMiddleware(epicMiddleware)); -const store = createStore(reducers); +epicMiddleware.run(epics); +store.dispatch(WorkloadActions.submit({ complexity: 100 })); + + +/* + +import * as WorkloadActions from './state/workloads/actions'; +import { WorkloadService } from './state/workloads/services'; + +// demo store store.subscribe(() => { console.log('store workload[0]', store.getState().workloads[0]); @@ -51,7 +60,6 @@ setTimeout(() => workloadService.checkStatus({ id: 2 }) .then(console.log.bind(console, 'checkStatus 2')), 200); -/* // pretend epic code function createWorkload(action$) { diff --git a/src/state/actions.ts b/src/state/actions.ts new file mode 100644 index 0000000..c38fe9f --- /dev/null +++ b/src/state/actions.ts @@ -0,0 +1,10 @@ +import * as WorkloadsActions from './workloads/actions'; +import { Action as WorkloadsAction } from './workloads/actions'; + +export type Action = WorkloadsAction; + +export const Actions = { + WorkloadsActions, +}; + +export default Actions; diff --git a/src/state/epics.ts b/src/state/epics.ts new file mode 100644 index 0000000..4cc1d7d --- /dev/null +++ b/src/state/epics.ts @@ -0,0 +1,7 @@ +import { combineEpics } from 'redux-observable'; + +import { epics as workloadsEpics } from './workloads'; + +export const epics = combineEpics(workloadsEpics); + +export default epics; \ No newline at end of file diff --git a/src/state/index.ts b/src/state/index.ts index 7732883..957be3f 100644 --- a/src/state/index.ts +++ b/src/state/index.ts @@ -1 +1,3 @@ -export * from './reducers'; \ No newline at end of file +export * from './reducers'; +export * from './actions'; +export * from './epics'; \ No newline at end of file diff --git a/src/state/reducers.ts b/src/state/reducers.ts index a749678..9a44e48 100644 --- a/src/state/reducers.ts +++ b/src/state/reducers.ts @@ -1,18 +1,17 @@ import { combineReducers } from 'redux'; +import { Action } from './actions'; + import { - Store as WorkloadsStore, - Action as WorkloadActions, + State as WorkloadsState, reducer as workloadReducer, } from './workloads'; -export type Action = WorkloadActions; - -export interface Store { - workloads: WorkloadsStore; +export interface State { + workloads: WorkloadsState; } -export const reducers = combineReducers({ +export const reducers = combineReducers({ workloads: workloadReducer, }); diff --git a/src/state/workloads/epics.ts b/src/state/workloads/epics.ts new file mode 100644 index 0000000..11a69e3 --- /dev/null +++ b/src/state/workloads/epics.ts @@ -0,0 +1,25 @@ +import { combineEpics, Epic, ofType } from 'redux-observable'; +import { map, tap, ignoreElements } from 'rxjs/operators'; + +import { Action } from '../actions'; +import { State } from '../reducers'; + + +type AppEpic = Epic; + + +const logWorkloadSubmissions: AppEpic = (action$, state$) => ( + action$.pipe( + ofType('WORKLOAD_SUBMIT'), + map(action => action.payload), + tap((payload) => console.log('Workload submitted', payload)), + ignoreElements(), + ) +); + + +export const epics = combineEpics( + logWorkloadSubmissions, +); + +export default epics; \ No newline at end of file diff --git a/src/state/workloads/index.ts b/src/state/workloads/index.ts index 97ebce8..9921edc 100644 --- a/src/state/workloads/index.ts +++ b/src/state/workloads/index.ts @@ -1,3 +1,4 @@ export * from './actions'; export * from './reducers'; +export * from './epics'; export * from './services'; diff --git a/src/state/workloads/reducers.ts b/src/state/workloads/reducers.ts index b0fb6e2..08f8017 100644 --- a/src/state/workloads/reducers.ts +++ b/src/state/workloads/reducers.ts @@ -1,20 +1,20 @@ import { Action } from './actions'; import { Status } from './types'; -interface Entry { - id: id; +interface Entry { + id: Id; completeDate: Date; status: Status; } -export type Store = { - [id in number]: Entry; +export type State = { + [Id in number]: Entry; }; -const initialState: Store = {}; +const initialState: State = {}; -export const reducer = (state: Store = initialState, action: Action): Store => { +export const reducer = (state: State = initialState, action: Action): State => { switch (action.type) { case 'WORKLOAD_CREATED': return { diff --git a/yarn.lock b/yarn.lock index c00aee0..1449897 100755 --- a/yarn.lock +++ b/yarn.lock @@ -8149,6 +8149,11 @@ recursive-readdir@2.2.2: dependencies: minimatch "3.0.4" +redux-observable@^1.0.0: + version "1.0.0" + resolved "https://npm.nutterlogic.com/redux-observable/-/redux-observable-1.0.0.tgz#780ff2455493eedcef806616fe286b454fd15d91" + integrity sha512-6bXnpqWTBeLaLQjXHyN1giXq4nLxCmv+SUkdmiwBgvmVxvDbdmydvL1Z7DGo0WItyzI/kqXQKiucUuTxnrPRkA== + redux@^4.0.0: version "4.0.1" resolved "https://npm.nutterlogic.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5" @@ -8472,6 +8477,13 @@ rxjs@^6.1.0: dependencies: tslib "^1.9.0" +rxjs@^6.4.0: + version "6.4.0" + resolved "https://npm.nutterlogic.com/rxjs/-/rxjs-6.4.0.tgz#f3bb0fe7bda7fb69deac0c16f17b50b0b8790504" + integrity sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw== + dependencies: + tslib "^1.9.0" + safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"