diff --git a/examples/containers/App.js b/examples/containers/App.js index 680d7bf8b8..890b1a3317 100644 --- a/examples/containers/App.js +++ b/examples/containers/App.js @@ -1,10 +1,14 @@ import React from 'react'; import CounterApp from './CounterApp'; import TodoApp from './TodoApp'; -import { createRedux, Provider } from 'redux'; +import { createRedux, composeStores, Provider } from 'redux'; +import createDispatcher from '../dispatcher/createDispatcher'; import * as stores from '../stores/index'; -const redux = createRedux(stores); +const store = composeStores(stores); +// You can modify these options while the code is running: +const dispatcher = createDispatcher(store, { log: true, replay: false }); +const redux = createRedux(dispatcher); export default class App { render() { diff --git a/examples/dispatcher/createDispatcher.js b/examples/dispatcher/createDispatcher.js new file mode 100644 index 0000000000..93b66526d1 --- /dev/null +++ b/examples/dispatcher/createDispatcher.js @@ -0,0 +1,73 @@ +function createDefaultReducer(store) { + return store; +} + +const REPLAY_STATE = Symbol('Replay State'); +function createReplayingReducer(store) { + return (state = {}, action) => { + let { + [REPLAY_STATE]: { actions = [], initialState = state } = {}, + ...appState + } = state; + + actions = [...actions, action]; + appState = actions.reduce(store, initialState); + + return { + [REPLAY_STATE]: { actions, initialState }, + ...appState + } + }; +} + +function createDefaultScheduler(dispatch, getState) { + function schedule(action) { + if (typeof action === 'function') { + return action(schedule, getState()); + } else { + return dispatch(action); + } + } + + return schedule; +} + +export default function createDispatcher(store, { + log = false, + replay = false +}: options = {}) { + return function dispatcher(initialState, setState) { + const reduce = replay ? + createReplayingReducer(store) : + createDefaultReducer(store); + + if (replay) { + console.debug('---- Replay Mode ----'); + } else { + console.debug('---- Normal Mode ----'); + } + console.debug('Initial state:', initialState); + + let state = reduce(initialState, {}); + setState(state); + + function dispatch(action) { + if (log) { + console.groupCollapsed(replay ? '[replay]' : '[normal]', action); + console.log('State before:', state); + } + + state = reduce(state, action); + setState(state); + + if (log) { + console.log('State after:', state); + console.groupEnd(replay ? '[replay]' : '[normal]', action); + } + + return action; + } + + return createDefaultScheduler(dispatch, () => state); + }; +}