diff --git a/package.json b/package.json index 89c33953..586ef1e2 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "react": "^0.14.0 || ^15.0.0-rc.1" }, "dependencies": { + "jsan": "^3.1.2", "lodash": "^4.2.0", "react-redux": "^4.0.0", "redux": "^3.2.1" diff --git a/src/persistState.js b/src/persistState.js index af7f6ac4..0cd20204 100644 --- a/src/persistState.js +++ b/src/persistState.js @@ -1,5 +1,6 @@ import mapValues from 'lodash/mapValues'; import identity from 'lodash/identity'; +import jsan from 'jsan'; export default function persistState(sessionId, deserializeState = identity, deserializeAction = identity) { if (!sessionId) { @@ -28,7 +29,7 @@ export default function persistState(sessionId, deserializeState = identity, des try { const json = localStorage.getItem(key); if (json) { - finalInitialState = deserialize(JSON.parse(json)) || initialState; + finalInitialState = deserialize(jsan.parse(json)) || initialState; next(reducer, initialState); } } catch (e) { @@ -48,7 +49,7 @@ export default function persistState(sessionId, deserializeState = identity, des store.dispatch(action); try { - localStorage.setItem(key, JSON.stringify(store.getState())); + localStorage.setItem(key, jsan.stringify(store.getState())); } catch (e) { console.warn('Could not write debug session to localStorage:', e); } diff --git a/test/persistState.spec.js b/test/persistState.spec.js index 763b6da7..18140682 100644 --- a/test/persistState.spec.js +++ b/test/persistState.spec.js @@ -88,6 +88,27 @@ describe('persistState', () => { expect(store2.getState()).toBe(-2); }); + it('should work with objects with circular references', () => { + const circularReducer = (state = { count: 0 }, action) => { + if (action.type === 'INCREMENT') { + const obj = { count: state.count + 1 }; + obj.self = obj; + return obj; + } + return state; + }; + + const store = createStore(circularReducer, compose(instrument(), persistState('id'))); + expect(store.getState().count).toBe(0); + + store.dispatch({ type: 'INCREMENT' }); + store.dispatch({ type: 'INCREMENT' }); + expect(store.getState().count).toBe(2); + + const store2 = createStore(circularReducer, compose(instrument(), persistState('id'))); + expect(store2.getState().count).toBe(2); + }); + it('should warn if read from localStorage fails', () => { const spy = expect.spyOn(console, 'warn'); delete global.localStorage.getItem;