Skip to content

Commit

Permalink
Proof of concept: enhancer overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon committed May 9, 2016
1 parent d4f8cb9 commit 880f717
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/applyMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import compose from './compose'
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, initialState, enhancer) => {
var store = createStore(reducer, initialState, enhancer)
var dispatch
var dispatch = store.dispatch
var chain = []

var middlewareAPI = {
Expand Down
63 changes: 34 additions & 29 deletions src/createStore.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import isPlainObject from 'lodash/isPlainObject'
import warning from './utils/warning'
import $$observable from 'symbol-observable'

export var ActionTypes = {
INIT: '@@redux/INIT'
}

function createBasicStore(reducer, initialState, onChange) {
function createStoreBase(reducer, initialState, onChange) {
var currentState = initialState
var isDispatching = false

Expand All @@ -30,58 +29,70 @@ function createBasicStore(reducer, initialState, onChange) {
if (isDispatching) {
throw new Error('Reducers may not dispatch actions.')
}

try {
isDispatching = true
currentState = reducer(currentState, action)
} finally {
isDispatching = false
}

onChange()
return action
}

return {
dispatch,
getState,
getState
}
}

export default function createEnhancedStore(reducer, initialState, enhancer) {
export default function createStore(reducer, initialState, enhancer) {
if (typeof reducer !== 'function') {
throw new Error('Expected the reducer to be a function.')
}
if (typeof initialState === 'function' && typeof enhancer === 'undefined') {
enhancer = initialState
initialState = undefined
}
var createStore = createBasicStore
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
createStore = enhancer(createBasicStore)
if (typeof enhancer !== 'undefined' && typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}

var store
enhancer = enhancer || (x => x)
var createFinalStoreBase = enhancer(createStoreBase)

var storeBase
var currentListeners = []
var nextListeners = currentListeners

function onChange() {
var listeners = currentListeners = nextListeners
for (var i = 0; i < listeners.length; i++) {
listeners[i]()
}
}

function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}

function subscribe(listener) {
if (typeof listener !== 'function') {
throw new Error('Expected listener to be a function.')
}

var isSubscribed = true
ensureCanMutateNextListeners()
nextListeners.push(listener)

return function unsubscribe() {
if (!isSubscribed) {
return
}

isSubscribed = false
ensureCanMutateNextListeners()
var index = nextListeners.indexOf(listener)
Expand All @@ -90,18 +101,21 @@ export default function createEnhancedStore(reducer, initialState, enhancer) {
}

function dispatch(action) {
return store.dispatch(action)
return storeBase.dispatch(action)
}

function onChange() {
var listeners = currentListeners = nextListeners
for (var i = 0; i < listeners.length; i++) {
listeners[i]()
}
function getState() {
return storeBase.getState()
}

function getState() {
return store.getState()
function replaceReducer(nextReducer) {
if (typeof nextReducer !== 'function') {
throw new Error('Expected the nextReducer to be a function.')
}

var nextInitialState = storeBase ? getState() : initialState
storeBase = createFinalStoreBase(nextReducer, nextInitialState, onChange)
dispatch({ type: ActionTypes.INIT })
}

function observable() {
Expand All @@ -126,15 +140,6 @@ export default function createEnhancedStore(reducer, initialState, enhancer) {
}
}

function replaceReducer(nextReducer) {
if (typeof nextReducer !== 'function') {
throw new Error('Expected the nextReducer to be a function.')
}

store = createStore(nextReducer, store ? getState() : initialState, onChange)
dispatch({ type: ActionTypes.INIT })
}

replaceReducer(reducer)

return {
Expand All @@ -144,4 +149,4 @@ export default function createEnhancedStore(reducer, initialState, enhancer) {
replaceReducer,
[$$observable]: observable
}
}
}

0 comments on commit 880f717

Please sign in to comment.