Skip to content

Commit

Permalink
Data: Add persistence via data plugin interface
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Aug 1, 2018
1 parent 54990c0 commit f380a13
Show file tree
Hide file tree
Showing 16 changed files with 224 additions and 428 deletions.
9 changes: 1 addition & 8 deletions edit-post/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { registerCoreBlocks } from '@wordpress/core-blocks';
import { render, unmountComponentAtNode } from '@wordpress/element';
import { dispatch, setupPersistence } from '@wordpress/data';
import { dispatch } from '@wordpress/data';
import deprecated from '@wordpress/deprecated';

/**
Expand All @@ -15,11 +15,6 @@ import store from './store';
import { initializeMetaBoxState } from './store/actions';
import Editor from './editor';

/**
* Module Constants
*/
const STORAGE_KEY = `WP_EDIT_POST_DATA_${ window.userSettings.uid }`;

/**
* Reinitializes the editor after the user chooses to reboot the editor after
* an unhandled error occurs, replacing previously mounted editor element using
Expand Down Expand Up @@ -93,5 +88,3 @@ export { default as PluginPostStatusInfo } from './components/sidebar/plugin-pos
export { default as PluginPrePublishPanel } from './components/sidebar/plugin-pre-publish-panel';
export { default as PluginSidebar } from './components/sidebar/plugin-sidebar';
export { default as PluginSidebarMoreMenuItem } from './components/header/plugin-sidebar-more-menu-item';

setupPersistence( STORAGE_KEY );
10 changes: 4 additions & 6 deletions edit-post/store/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
/**
* WordPress Dependencies
*/
import {
registerStore,
restrictPersistence,
} from '@wordpress/data';
import { registerStore } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -13,11 +10,12 @@ import reducer from './reducer';
import applyMiddlewares from './middlewares';
import * as actions from './actions';
import * as selectors from './selectors';

const store = registerStore( 'core/edit-post', {
reducer: restrictPersistence( reducer, 'preferences' ),
reducer,
actions,
selectors,
persist: true,
persist: [ 'preferences' ],
} );

applyMiddlewares( store );
Expand Down
23 changes: 22 additions & 1 deletion lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ function gutenberg_register_scripts_and_styles() {
filemtime( gutenberg_dir_path() . 'build/is-shallow-equal/index.js' ),
true
);
wp_register_script(
'wp-data-plugin-persistence',
gutenberg_url( 'build/data-plugin-persistence/index.js' ),
array( 'wp-is-shallow-equal' ),
filemtime( gutenberg_dir_path() . 'build/data-plugin-persistence/index.js' ),
true
);

// Editor Scripts.
wp_register_script(
Expand Down Expand Up @@ -376,10 +383,24 @@ function gutenberg_register_scripts_and_styles() {
wp_register_script(
'wp-nux',
gutenberg_url( 'build/nux/index.js' ),
array( 'wp-element', 'wp-components', 'wp-compose', 'wp-data', 'wp-i18n', 'lodash' ),
array(
'lodash',
'wp-components',
'wp-compose',
'wp-data',
'wp-data-plugin-persistence',
'wp-element',
'wp-i18n',
),
filemtime( gutenberg_dir_path() . 'build/nux/index.js' ),
true
);
wp_add_inline_script(
'wp-nux',
'wp.data.use( wp.dataPluginPersistence.createPersistencePlugin( "WP_EDIT_POST_DATA_" + window.userSettings.uid ) );',
'before'
);

// Loading the old editor and its config to ensure the classic block works as expected.
wp_add_inline_script(
'editor', 'window.wp.oldEditor = window.wp.editor;', 'after'
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@wordpress/compose": "file:packages/compose",
"@wordpress/core-data": "file:packages/core-data",
"@wordpress/data": "file:packages/data",
"@wordpress/data-plugin-persistence": "file:packages/data-plugin-persistence",
"@wordpress/date": "file:packages/date",
"@wordpress/deprecated": "file:packages/deprecated",
"@wordpress/dom": "file:packages/dom",
Expand Down
1 change: 1 addition & 0 deletions packages/data-plugin-persistence/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
29 changes: 29 additions & 0 deletions packages/data-plugin-persistence/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@wordpress/data-plugin-persistence",
"version": "1.0.1",
"description": "Data module plugin for persistence.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
"keywords": [
"wordpress",
"data"
],
"homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/data-plugin-persistence/README.md",
"repository": {
"type": "git",
"url": "https://github.com/WordPress/gutenberg.git"
},
"bugs": {
"url": "https://github.com/WordPress/gutenberg/issues"
},
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
"dependencies": {
"@babel/runtime": "^7.0.0-beta.52",
"@wordpress/is-shallow-equal": "file:../is-shallow-equal"
},
"publishConfig": {
"access": "public"
}
}
120 changes: 120 additions & 0 deletions packages/data-plugin-persistence/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* WordPress dependencies
*/
import isShallowEqual from '@wordpress/is-shallow-equal';

// Defaults to the local storage.
let persistenceStorage;

/**
* Sets a different persistence storage.
*
* @param {Object} storage Persistence storage.
*/
export function setPersistenceStorage( storage ) {
persistenceStorage = storage;
}

/**
* Get the persistence storage handler.
*
* @return {Object} Persistence storage.
*/
export function getPersistenceStorage() {
return persistenceStorage || window.localStorage;
}

/**
* Higher-order reducer used to persist just one key from the reducer state.
*
* @param {function} reducer Reducer function.
* @param {string} keyToPersist The reducer key to persist.
*
* @return {function} Updated reducer.
*/
export function restrictPersistence( reducer, keyToPersist ) {
return ( state, action ) => {
const nextState = reducer( state, action );

if ( action.type === 'SERIALIZE' ) {
// Returning the same instance if the state is kept identical avoids reserializing again
if (
action.previousState &&
action.previousState[ keyToPersist ] === nextState[ keyToPersist ]
) {
return action.previousState;
}

return { [ keyToPersist ]: nextState[ keyToPersist ] };
}

return nextState;
};
}

export function createPersistencePlugin( storageKey ) {
return ( registry ) => {
const { namespaces, subscribe } = registry;
const persisted = Object.create( null );

// Load initially persisted value
const persistedString = getPersistenceStorage().getItem( storageKey );
const persistedData = persistedString ? JSON.parse( persistedString ) : {};
let previousValue = null;

const triggerPersist = () => {
const newValue = Object.entries( namespaces )
.filter( ( [ reducerKey ] ) => persisted[ reducerKey ] )
.reduce( ( memo, [ reducerKey, { reducer, store } ] ) => {
const action = { type: 'SERIALIZE' };
if ( previousValue ) {
action.previousState = previousValue[ reducerKey ];
}

memo[ reducerKey ] = reducer( store.getState(), action );
return memo;
}, {} );

if ( ! isShallowEqual( newValue, previousValue ) ) {
getPersistenceStorage().setItem( storageKey, JSON.stringify( newValue ) );
}

previousValue = newValue;
};

function withInitialState( reducerKey, reducer ) {
return ( state, action ) => {
if ( state === undefined ) {
state = persistedData[ reducerKey ];
}

return reducer( state, action );
};
}

// Persist updated preferences
subscribe( triggerPersist );

return {
registerStore( reducerKey, options ) {
options = {
...options,
reducer: withInitialState( reducerKey, options.reducer ),
};

if ( options.persist ) {
persisted[ reducerKey ] = true;

if ( Array.isArray( options.persist ) ) {
options.reducer = options.persist.reduce(
restrictPersistence,
options.reducer,
);
}
}

return registry.registerStore( reducerKey, options );
},
};
};
}
1 change: 0 additions & 1 deletion packages/data/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
"@wordpress/compose": "file:../compose",
"@wordpress/deprecated": "file:../deprecated",
"@wordpress/element": "file:../element",
"@wordpress/is-shallow-equal": "file:../is-shallow-equal",
"equivalent-key-map": "^0.2.1",
"lodash": "^4.17.10",
"redux": "^3.7.2"
Expand Down
91 changes: 0 additions & 91 deletions packages/data/src/deprecated.js

This file was deleted.

5 changes: 2 additions & 3 deletions packages/data/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ import { combineReducers } from 'redux';
* Internal dependencies
*/
import defaultRegistry from './default-registry';
export { restrictPersistence, setPersistenceStorage } from './persist';
export { default as withSelect } from './components/with-select';
export { default as withDispatch } from './components/with-dispatch';
export { default as RegistryProvider } from './components/registry-provider';
export { createRegistry } from './registry';
export { withRehydration, loadAndPersist } from './deprecated';

/**
* The combineReducers helper function turns an object whose values are different
Expand All @@ -34,4 +32,5 @@ export const registerReducer = defaultRegistry.registerReducer;
export const registerActions = defaultRegistry.registerActions;
export const registerSelectors = defaultRegistry.registerSelectors;
export const registerResolvers = defaultRegistry.registerResolvers;
export const setupPersistence = defaultRegistry.setupPersistence;
export const namespaces = defaultRegistry.namespaces;
export const use = defaultRegistry.use;
Loading

0 comments on commit f380a13

Please sign in to comment.