Skip to content

Commit

Permalink
Implemented mechanism to allow reducers to customise what information…
Browse files Browse the repository at this point in the history
… gets serialised to localStorage; Changed mechanism to load defaults in loadAndPersist.
  • Loading branch information
jorgefilipecosta committed Jan 18, 2018
1 parent 1fa9344 commit 4d6af27
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 22 deletions.
3 changes: 1 addition & 2 deletions editor/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { registerReducer, registerSelectors } from '@wordpress/data';
/**
* Internal dependencies
*/
import { PREFERENCES_DEFAULTS } from './defaults';
import reducer from './reducer';
import { withRehydratation, loadAndPersist } from './persist';
import enhanceWithBrowserSize from './mobile';
Expand All @@ -23,7 +22,7 @@ const MODULE_KEY = 'core/editor';
const store = applyMiddlewares(
registerReducer( 'core/editor', withRehydratation( reducer, 'preferences' ) )
);
loadAndPersist( store, 'preferences', STORAGE_KEY, PREFERENCES_DEFAULTS );
loadAndPersist( store, reducer, 'preferences', STORAGE_KEY );
enhanceWithBrowserSize( store, BREAK_MEDIUM );

registerSelectors( MODULE_KEY, { getEditedPostTitle } );
Expand Down
15 changes: 8 additions & 7 deletions editor/store/persist.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@ export function withRehydratation( reducer, reducerKey ) {
*
* This should be executed after the reducer's registration.
*
* @param {Object} store Store to enhance.
* @param {string} reducerKey The reducer key to persist (example: reducerKey.subReducerKey).
* @param {string} storageKey The storage key to use.
* @param {Object} defaults Default values of the reducer key.
* @param {Object} store Store to enhance.
* @param {Function} reducer The reducer function. Used to get default values and to allow custom serialization by the reducers.
* @param {string} reducerKey The reducer key to persist (example: reducerKey.subReducerKey).
* @param {string} storageKey The storage key to use.
*/
export function loadAndPersist( store, reducerKey, storageKey, defaults = {} ) {
export function loadAndPersist( store, reducer, reducerKey, storageKey ) {
// Load initially persisted value
const persistedString = window.localStorage.getItem( storageKey );
if ( persistedString ) {
const persistedState = {
...defaults,
...get( reducer( undefined, { type: 'DEFAULTS' } ), reducerKey ),
...JSON.parse( persistedString ),
};

Expand All @@ -60,7 +60,8 @@ export function loadAndPersist( store, reducerKey, storageKey, defaults = {} ) {
const newStateValue = get( store.getState(), reducerKey );
if ( newStateValue !== currentStateValue ) {
currentStateValue = newStateValue;
window.localStorage.setItem( storageKey, JSON.stringify( currentStateValue ) );
const stateToSave = get( reducer( store.getState(), { type: 'REDUX_SERIALIZE' } ), reducerKey );
window.localStorage.setItem( storageKey, JSON.stringify( stateToSave ) );
}
} );
}
28 changes: 15 additions & 13 deletions editor/store/test/persist.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { createStore } from 'redux';
import { loadAndPersist, withRehydratation } from '../persist';

describe( 'loadAndPersist', () => {
it( 'should load the initial value from the local storage', () => {
it( 'should load the initial value from the local storage integrating it into reducer default value.', () => {
const storageKey = 'dumbStorageKey';
window.localStorage.setItem( storageKey, JSON.stringify( { chicken: true } ) );
const reducer = () => {
Expand All @@ -20,15 +20,20 @@ describe( 'loadAndPersist', () => {
const store = createStore( withRehydratation( reducer, 'preferences' ) );
loadAndPersist(
store,
reducer,
'preferences',
storageKey,
);
expect( store.getState().preferences ).toEqual( { chicken: true } );
expect( store.getState().preferences ).toEqual( { chicken: true, ribs: true } );
} );

it( 'should persit to local storage once the state value changes', () => {
it( 'should persist to local storage once the state value changes', () => {
const storageKey = 'dumbStorageKey2';
const reducer = ( state, action ) => {
if ( action.type === 'REDUX_SERIALIZE' ) {
return state;
}

if ( action.type === 'UPDATE' ) {
return {
preferences: { chicken: true },
Expand All @@ -42,6 +47,7 @@ describe( 'loadAndPersist', () => {
const store = createStore( withRehydratation( reducer, 'preferences' ) );
loadAndPersist(
store,
reducer,
'preferences',
storageKey,
);
Expand All @@ -54,15 +60,13 @@ describe( 'loadAndPersist', () => {
counter: 41,
};
const storageKey = 'dumbStorageKey3';
const reducer = ( state, action ) => {
const reducer = ( state = { preferences: defaultsPreferences }, action ) => {
if ( action.type === 'INCREMENT' ) {
return {
preferences: { counter: state.preferences.counter + 1 },
};
}
return {
preferences: { counter: 0 },
};
return state;
};

// store preferences without the `counter` default
Expand All @@ -71,9 +75,9 @@ describe( 'loadAndPersist', () => {
const store = createStore( withRehydratation( reducer, 'preferences' ) );
loadAndPersist(
store,
reducer,
'preferences',
storageKey,
defaultsPreferences,
);
store.dispatch( { type: 'INCREMENT' } );

Expand All @@ -87,15 +91,13 @@ describe( 'loadAndPersist', () => {
counter: 41,
};
const storageKey = 'dumbStorageKey4';
const reducer = ( state, action ) => {
const reducer = ( state = { preferences: defaultsPreferences }, action ) => {
if ( action.type === 'INCREMENT' ) {
return {
preferences: { counter: state.preferences.counter + 1 },
};
}
return {
preferences: { counter: 0 },
};
return state;
};

window.localStorage.setItem( storageKey, JSON.stringify( { counter: 1 } ) );
Expand All @@ -104,9 +106,9 @@ describe( 'loadAndPersist', () => {

loadAndPersist(
store,
reducer,
'preferences',
storageKey,
defaultsPreferences,
);
store.dispatch( { type: 'INCREMENT' } );

Expand Down

0 comments on commit 4d6af27

Please sign in to comment.