diff --git a/package-lock.json b/package-lock.json index b22ddbae695e83..ddcf2d015db65c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17530,7 +17530,6 @@ "@wordpress/shortcode": "file:packages/shortcode", "@wordpress/token-list": "file:packages/token-list", "@wordpress/url": "file:packages/url", - "@wordpress/viewport": "file:packages/viewport", "@wordpress/warning": "file:packages/warning", "@wordpress/wordcount": "file:packages/wordcount", "classnames": "^2.2.5", @@ -18018,7 +18017,6 @@ "@wordpress/rich-text": "file:packages/rich-text", "@wordpress/server-side-render": "file:packages/server-side-render", "@wordpress/url": "file:packages/url", - "@wordpress/viewport": "file:packages/viewport", "@wordpress/wordcount": "file:packages/wordcount", "classnames": "^2.2.5", "lodash": "^4.17.19", @@ -18146,6 +18144,7 @@ "@wordpress/i18n": "file:packages/i18n", "@wordpress/icons": "file:packages/icons", "@wordpress/plugins": "file:packages/plugins", + "@wordpress/viewport": "file:packages/viewport", "classnames": "^2.2.5", "lodash": "^4.17.19" } diff --git a/packages/annotations/src/format/annotation.js b/packages/annotations/src/format/annotation.js index 9ce2a2bd6d456f..f3ea7096a37827 100644 --- a/packages/annotations/src/format/annotation.js +++ b/packages/annotations/src/format/annotation.js @@ -7,7 +7,7 @@ import { applyFormat, removeFormat } from '@wordpress/rich-text'; const FORMAT_NAME = 'core/annotation'; const ANNOTATION_ATTRIBUTE_PREFIX = 'annotation-text-'; -const STORE_KEY = 'core/annotations'; +const STORE_NAME = 'core/annotations'; /** * Applies given annotations to the given record. @@ -145,7 +145,7 @@ export const annotation = { ) { return { annotations: select( - STORE_KEY + STORE_NAME ).__experimentalGetAnnotationsForRichText( blockClientId, richTextIdentifier @@ -165,9 +165,9 @@ export const annotation = { }, __experimentalGetPropsForEditableTreeChangeHandler( dispatch ) { return { - removeAnnotation: dispatch( STORE_KEY ) + removeAnnotation: dispatch( STORE_NAME ) .__experimentalRemoveAnnotation, - updateAnnotationRange: dispatch( STORE_KEY ) + updateAnnotationRange: dispatch( STORE_NAME ) .__experimentalUpdateAnnotationRange, }; }, diff --git a/packages/annotations/src/index.js b/packages/annotations/src/index.js index 9435b1d8616616..4624351fd98a6e 100644 --- a/packages/annotations/src/index.js +++ b/packages/annotations/src/index.js @@ -1,6 +1,7 @@ /** * Internal dependencies */ -import './store'; import './format'; import './block'; + +export { store } from './store'; diff --git a/packages/annotations/src/store/index.js b/packages/annotations/src/store/index.js index 1c7f27dccbc351..81dee6efd82b44 100644 --- a/packages/annotations/src/store/index.js +++ b/packages/annotations/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { register, createReduxStore } from '@wordpress/data'; /** * Internal dependencies @@ -13,12 +13,19 @@ import * as actions from './actions'; /** * Module Constants */ -const MODULE_KEY = 'core/annotations'; +const STORE_NAME = 'core/annotations'; -const store = registerStore( MODULE_KEY, { +/** + * Store definition for the annotations namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { reducer, selectors, actions, } ); -export default store; +register( store ); diff --git a/packages/block-directory/src/index.js b/packages/block-directory/src/index.js index 1c5eccc183bc29..673db466448953 100644 --- a/packages/block-directory/src/index.js +++ b/packages/block-directory/src/index.js @@ -6,5 +6,6 @@ import '@wordpress/notices'; /** * Internal dependencies */ -import './store'; import './plugins'; + +export { store } from './store'; diff --git a/packages/block-directory/src/store/index.js b/packages/block-directory/src/store/index.js index 8e81d70023084c..ca3f2c8b939dd6 100644 --- a/packages/block-directory/src/store/index.js +++ b/packages/block-directory/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, register } from '@wordpress/data'; import { controls as dataControls } from '@wordpress/data-controls'; /** @@ -16,7 +16,7 @@ import controls from './controls'; /** * Module Constants */ -const MODULE_KEY = 'core/block-directory'; +const STORE_NAME = 'core/block-directory'; /** * Block editor data store configuration. @@ -33,6 +33,13 @@ export const storeConfig = { resolvers, }; -const store = registerStore( MODULE_KEY, storeConfig ); +/** + * Store definition for the block directory namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, storeConfig ); -export default store; +register( store ); diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 5865e820d1d79d..cfadf407b3b655 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -504,6 +504,18 @@ _Properties_ Undocumented declaration. +# **store** + +Store definition for the block editor namespace. + +_Related_ + +- + +_Type_ + +- `Object` + # **storeConfig** Block editor data store configuration. diff --git a/packages/block-editor/package.json b/packages/block-editor/package.json index 7fc434dc3e5650..b8264cfd2e8ee4 100644 --- a/packages/block-editor/package.json +++ b/packages/block-editor/package.json @@ -50,7 +50,6 @@ "@wordpress/shortcode": "file:../shortcode", "@wordpress/token-list": "file:../token-list", "@wordpress/url": "file:../url", - "@wordpress/viewport": "file:../viewport", "@wordpress/warning": "file:../warning", "@wordpress/wordcount": "file:../wordcount", "classnames": "^2.2.5", diff --git a/packages/block-editor/src/index.js b/packages/block-editor/src/index.js index 037b0f8fad5f17..1e12ca9f4acaed 100644 --- a/packages/block-editor/src/index.js +++ b/packages/block-editor/src/index.js @@ -3,7 +3,6 @@ */ import '@wordpress/blocks'; import '@wordpress/rich-text'; -import '@wordpress/viewport'; import '@wordpress/keyboard-shortcuts'; import '@wordpress/notices'; @@ -13,5 +12,5 @@ import '@wordpress/notices'; import './hooks'; export * from './components'; export * from './utils'; -export { storeConfig } from './store'; +export { storeConfig, store } from './store'; export { SETTINGS_DEFAULTS } from './store/defaults'; diff --git a/packages/block-editor/src/store/index.js b/packages/block-editor/src/store/index.js index bfc7766a508762..8fd1f3532c632c 100644 --- a/packages/block-editor/src/store/index.js +++ b/packages/block-editor/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, registerStore } from '@wordpress/data'; /** * Internal dependencies @@ -15,7 +15,7 @@ import controls from './controls'; /** * Module Constants */ -const MODULE_KEY = 'core/block-editor'; +const STORE_NAME = 'core/block-editor'; /** * Block editor data store configuration. @@ -31,10 +31,23 @@ export const storeConfig = { controls, }; -const store = registerStore( MODULE_KEY, { +/** + * Store definition for the block editor namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { ...storeConfig, persist: [ 'preferences' ], } ); -applyMiddlewares( store ); -export default store; +// Ideally we'd use register instead of register stores. +// We should be able to make the switch once we remove the "effects" middleware. +// We also need a more generic way of defining persistence and not rely on a plugin. +const instantiatedStore = registerStore( STORE_NAME, { + ...storeConfig, + persist: [ 'preferences' ], +} ); +applyMiddlewares( instantiatedStore ); diff --git a/packages/blocks/README.md b/packages/blocks/README.md index 9116c3e5490c9e..233883c81b7ee4 100644 --- a/packages/blocks/README.md +++ b/packages/blocks/README.md @@ -740,6 +740,18 @@ _Parameters_ - _blockName_ `string`: Block name. +# **store** + +Store definition for the blocks namespace. + +_Related_ + +- + +_Type_ + +- `Object` + # **switchToBlockType** Switch one or more blocks into one or more blocks of the new block type. diff --git a/packages/blocks/src/index.js b/packages/blocks/src/index.js index 579665d14b8538..0af3f5e0ae720d 100644 --- a/packages/blocks/src/index.js +++ b/packages/blocks/src/index.js @@ -8,10 +8,6 @@ // Blocks are inferred from the HTML source of a post through a parsing mechanism // and then stored as objects in state, from which it is then rendered for editing. -/** - * Internal dependencies - */ -import './store'; - +export { store } from './store'; export * from './api'; export { withBlockContentContext } from './block-content-provider'; diff --git a/packages/blocks/src/store/index.js b/packages/blocks/src/store/index.js index 4ba62857cb05cf..7672b6e5e7fb85 100644 --- a/packages/blocks/src/store/index.js +++ b/packages/blocks/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, register } from '@wordpress/data'; /** * Internal dependencies @@ -10,4 +10,19 @@ import reducer from './reducer'; import * as selectors from './selectors'; import * as actions from './actions'; -registerStore( 'core/blocks', { reducer, selectors, actions } ); +const STORE_NAME = 'core/blocks'; + +/** + * Store definition for the blocks namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { + reducer, + selectors, + actions, +} ); + +register( store ); diff --git a/packages/core-data/src/index.js b/packages/core-data/src/index.js index 9c34fabe40d76e..fc2c051a52165a 100644 --- a/packages/core-data/src/index.js +++ b/packages/core-data/src/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, register } from '@wordpress/data'; import { controls } from '@wordpress/data-controls'; /** @@ -14,7 +14,7 @@ import * as resolvers from './resolvers'; import * as locksSelectors from './locks/selectors'; import * as locksActions from './locks/actions'; import { defaultEntities, getMethodName } from './entities'; -import { REDUCER_KEY } from './name'; +import { STORE_NAME } from './name'; // The entity selectors/resolvers and actions are shortcuts to their generic equivalents // (getEntityRecord, getEntityRecords, updateEntityRecord, updateEntityRecordss) @@ -56,14 +56,24 @@ const entityActions = defaultEntities.reduce( ( result, entity ) => { return result; }, {} ); -export const storeConfig = { +const storeConfig = { reducer, controls, actions: { ...actions, ...entityActions, ...locksActions }, selectors: { ...selectors, ...entitySelectors, ...locksSelectors }, resolvers: { ...resolvers, ...entityResolvers }, }; -registerStore( REDUCER_KEY, storeConfig ); + +/** + * Store definition for the code data namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, storeConfig ); + +register( store ); export { default as EntityProvider } from './entity-provider'; export * from './entity-provider'; diff --git a/packages/core-data/src/name.js b/packages/core-data/src/name.js index 6049841dc94a53..eb5122fbee117f 100644 --- a/packages/core-data/src/name.js +++ b/packages/core-data/src/name.js @@ -4,4 +4,4 @@ * * @type {string} */ -export const REDUCER_KEY = 'core'; +export const STORE_NAME = 'core'; diff --git a/packages/core-data/src/selectors.js b/packages/core-data/src/selectors.js index c78cda23ff49df..42f442809c952c 100644 --- a/packages/core-data/src/selectors.js +++ b/packages/core-data/src/selectors.js @@ -13,7 +13,7 @@ import deprecated from '@wordpress/deprecated'; /** * Internal dependencies */ -import { REDUCER_KEY } from './name'; +import { STORE_NAME } from './name'; import { getQueriedItems } from './queried-data'; import { DEFAULT_ENTITY_KEY } from './entities'; import { getNormalizedCommaSeparable } from './utils'; @@ -41,7 +41,7 @@ const EMPTY_ARRAY = []; export const isRequestingEmbedPreview = createRegistrySelector( ( select ) => ( state, url ) => { return select( 'core/data' ).isResolving( - REDUCER_KEY, + STORE_NAME, 'getEmbedPreview', [ url ] ); @@ -692,7 +692,7 @@ export function getAutosave( state, postType, postId, authorId ) { */ export const hasFetchedAutosaves = createRegistrySelector( ( select ) => ( state, postType, postId ) => { - return select( REDUCER_KEY ).hasFinishedResolution( 'getAutosaves', [ + return select( STORE_NAME ).hasFinishedResolution( 'getAutosaves', [ postType, postId, ] ); diff --git a/packages/core-data/src/test/integration.js b/packages/core-data/src/test/integration.js index d0b04dac3cc701..43fbdaeb27bd97 100644 --- a/packages/core-data/src/test/integration.js +++ b/packages/core-data/src/test/integration.js @@ -9,7 +9,7 @@ import { createRegistry, controls } from '@wordpress/data'; import * as actions from '../actions'; import * as selectors from '../selectors'; import * as resolvers from '../resolvers'; -import { storeConfig as coreStoreConfig } from '../'; +import { store } from '../'; // Mock to prevent calling window.fetch in test environment jest.mock( '@wordpress/data-controls', () => { @@ -52,7 +52,7 @@ describe( 'receiveEntityRecord', () => { data: {}, }, }; - registry.registerStore( 'core', coreStoreConfig ); + registry.register( store ); registry.registerStore( 'test/resolution', { actions: { receiveEntityRecords: actions.receiveEntityRecords, @@ -160,7 +160,7 @@ describe( 'receiveEntityRecord', () => { describe( 'saveEntityRecord', () => { function createTestRegistry() { const registry = createRegistry(); - registry.registerStore( 'core', coreStoreConfig ); + registry.register( store ); return registry; } diff --git a/packages/data/README.md b/packages/data/README.md index a7534458b3731d..b55e0e8421745c 100644 --- a/packages/data/README.md +++ b/packages/data/README.md @@ -80,7 +80,7 @@ registerStore( 'my-shop', { const { prices, discountPercent } = state; const price = prices[ item ]; - return price * ( 1 - ( 0.01 * discountPercent ) ); + return price * ( 1 - 0.01 * discountPercent ); }, }, @@ -91,7 +91,7 @@ registerStore( 'my-shop', { }, resolvers: { - * getPrice( item ) { + *getPrice( item ) { const path = '/wp/v2/prices/' + item; const price = yield actions.fetchFromAPI( path ); return actions.setPrice( item, price ); @@ -151,7 +151,7 @@ The `@wordpress/data` module offers a more advanced and generic interface for th - Behaves as Redux [`subscribe`](https://redux.js.org/api/store#subscribelistener) with the following differences: - Doesn't have to implement an unsubscribe, since the registry never uses it. - \- Only has to support one listener (the registry). + \- Only has to support one listener (the registry). By implementing the above interface for your custom store, you gain the benefits of using the registry and the `withSelect` and `withDispatch` higher order components in your application code. This provides seamless integration with existing and alternative data systems. @@ -168,16 +168,23 @@ const { registerGenericStore } = wp.data; const reduxStore = createStore(); -const mappedSelectors = Object.keys( existingSelectors ).reduce( ( acc, selectorKey ) => { - acc[ selectorKey ] = ( ...args ) => - existingSelectors[ selectorKey ]( reduxStore.getState(), ...args ); - return acc; -}, {} ); - -const mappedActions = Object.keys( existingActions ).reduce( ( acc, actionKey ) => { - acc[ actionKey ] = ( ...args ) => reduxStore.dispatch( existingActions[ actionKey ]( ...args ) ); - return acc; -}, {} ); +const mappedSelectors = Object.keys( existingSelectors ).reduce( + ( acc, selectorKey ) => { + acc[ selectorKey ] = ( ...args ) => + existingSelectors[ selectorKey ]( reduxStore.getState(), ...args ); + return acc; + }, + {} +); + +const mappedActions = Object.keys( existingActions ).reduce( + ( acc, actionKey ) => { + acc[ actionKey ] = ( ...args ) => + reduxStore.dispatch( existingActions[ actionKey ]( ...args ) ); + return acc; + }, + {} +); const genericStore = { getSelectors() { @@ -201,7 +208,7 @@ const { registerGenericStore } = wp.data; function createCustomStore() { let storeChanged = () => {}; - const prices = { hammer: 7.50 }; + const prices = { hammer: 7.5 }; const selectors = { getPrice( itemName ) { @@ -225,7 +232,7 @@ function createCustomStore() { }, subscribe( listener ) { storeChanged = listener; - } + }, }; } @@ -338,6 +345,19 @@ _Returns_ Undocumented declaration. +# **createReduxStore** + +Creates a namespace object with a store derived from the reducer given. + +_Parameters_ + +- _key_ `string`: Unique namespace identifier. +- _options_ (unknown type): Registered store options, with properties describing reducer, actions, selectors, and resolvers. + +_Returns_ + +- (unknown type): Store Object. + # **createRegistry** Creates a new store registry, given an optional object of initial store @@ -463,6 +483,14 @@ _Type_ - `Object` +# **register** + +Registers a standard `@wordpress/data` store definition. + +_Parameters_ + +- _store_ (unknown type): Store definition. + # **registerGenericStore** Registers a generic store. @@ -478,7 +506,7 @@ Registers a standard `@wordpress/data` store. _Parameters_ -- _reducerKey_ `string`: Reducer key. +- _storeName_ `string`: Unique namespace identifier for the store. - _options_ `Object`: Store description (reducer, actions, selectors, resolvers). _Returns_ diff --git a/packages/data/src/index.js b/packages/data/src/index.js index 911b6e02983798..7e19c370b65ba8 100644 --- a/packages/data/src/index.js +++ b/packages/data/src/index.js @@ -23,6 +23,7 @@ export { AsyncModeProvider } from './components/async-mode-provider'; export { createRegistry } from './registry'; export { createRegistrySelector, createRegistryControl } from './factory'; export { controls } from './controls'; +export { default as createReduxStore } from './redux-store'; /** * Object of available plugins to use with a registry. @@ -162,8 +163,8 @@ export const registerGenericStore = defaultRegistry.registerGenericStore; /** * Registers a standard `@wordpress/data` store. * - * @param {string} reducerKey Reducer key. - * @param {Object} options Store description (reducer, actions, selectors, resolvers). + * @param {string} storeName Unique namespace identifier for the store. + * @param {Object} options Store description (reducer, actions, selectors, resolvers). * * @return {Object} Registered store object. */ @@ -177,3 +178,10 @@ export const registerStore = defaultRegistry.registerStore; * @param {Object} plugin Plugin object. */ export const use = defaultRegistry.use; + +/** + * Registers a standard `@wordpress/data` store definition. + * + * @param {import('./types').WPDataStore} store Store definition. + */ +export const register = defaultRegistry.register; diff --git a/packages/data/src/plugins/persistence/index.js b/packages/data/src/plugins/persistence/index.js index fc9ae014d4628f..cfebe55cac98d8 100644 --- a/packages/data/src/plugins/persistence/index.js +++ b/packages/data/src/plugins/persistence/index.js @@ -126,15 +126,15 @@ function persistencePlugin( registry, pluginOptions ) { /** * Creates an enhanced store dispatch function, triggering the state of the - * given reducer key to be persisted when changed. + * given store name to be persisted when changed. * - * @param {Function} getState Function which returns current state. - * @param {string} reducerKey Reducer key. - * @param {?Array} keys Optional subset of keys to save. + * @param {Function} getState Function which returns current state. + * @param {string} storeName Store name. + * @param {?Array} keys Optional subset of keys to save. * * @return {Function} Enhanced dispatch function. */ - function createPersistOnChange( getState, reducerKey, keys ) { + function createPersistOnChange( getState, storeName, keys ) { let getPersistedState; if ( Array.isArray( keys ) ) { // Given keys, the persisted state should by produced as an object @@ -166,20 +166,20 @@ function persistencePlugin( registry, pluginOptions ) { nextState: getState(), } ); if ( state !== lastState ) { - persistence.set( reducerKey, state ); + persistence.set( storeName, state ); lastState = state; } }; } return { - registerStore( reducerKey, options ) { + registerStore( storeName, options ) { if ( ! options.persist ) { - return registry.registerStore( reducerKey, options ); + return registry.registerStore( storeName, options ); } // Load from persistence to use as initial state. - const persistedState = persistence.get()[ reducerKey ]; + const persistedState = persistence.get()[ storeName ]; if ( persistedState !== undefined ) { let initialState = options.reducer( options.initialState, { type: '@@WP/PERSISTENCE_RESTORE', @@ -207,12 +207,12 @@ function persistencePlugin( registry, pluginOptions ) { }; } - const store = registry.registerStore( reducerKey, options ); + const store = registry.registerStore( storeName, options ); store.subscribe( createPersistOnChange( store.getState, - reducerKey, + storeName, options.persist ) ); diff --git a/packages/data/src/namespace-store/index.js b/packages/data/src/redux-store/index.js similarity index 69% rename from packages/data/src/namespace-store/index.js rename to packages/data/src/redux-store/index.js index 8ce882f0e6be8b..4fb635d2ba8dce 100644 --- a/packages/data/src/namespace-store/index.js +++ b/packages/data/src/redux-store/index.js @@ -49,114 +49,115 @@ function createResolversCache() { }; } -/** - * @typedef {WPDataRegistry} WPDataRegistry - */ - /** * Creates a namespace object with a store derived from the reducer given. * - * @param {string} key Unique namespace identifier. - * @param {Object} options Registered store options, with properties - * describing reducer, actions, selectors, and - * resolvers. - * @param {WPDataRegistry} registry Registry reference. + * @param {string} key Unique namespace identifier. + * @param {import('../types').WPDataReduxStoreConfig} options Registered store options, with properties + * describing reducer, actions, selectors, and + * resolvers. * - * @return {Object} Store Object. + * @return {import('../types').WPDataStoreDefinition} Store Object. */ -export default function createNamespace( key, options, registry ) { - const reducer = options.reducer; - const store = createReduxStore( key, options, registry ); - const resolversCache = createResolversCache(); - - let resolvers; - const actions = mapActions( - { - ...metadataActions, - ...options.actions, - }, - store - ); - let selectors = mapSelectors( - { - ...mapValues( - metadataSelectors, - ( selector ) => ( state, ...args ) => - selector( state.metadata, ...args ) - ), - ...mapValues( options.selectors, ( selector ) => { - if ( selector.isRegistrySelector ) { - selector.registry = registry; - } - - return ( state, ...args ) => selector( state.root, ...args ); - } ), - }, - store - ); - if ( options.resolvers ) { - const result = mapResolvers( - options.resolvers, - selectors, - store, - resolversCache - ); - resolvers = result.resolvers; - selectors = result.selectors; - } +export default function createReduxStore( key, options ) { + return { + name: key, + instantiate: ( registry ) => { + const reducer = options.reducer; + const store = instantiateReduxStore( key, options, registry ); + const resolversCache = createResolversCache(); + + let resolvers; + const actions = mapActions( + { + ...metadataActions, + ...options.actions, + }, + store + ); + let selectors = mapSelectors( + { + ...mapValues( + metadataSelectors, + ( selector ) => ( state, ...args ) => + selector( state.metadata, ...args ) + ), + ...mapValues( options.selectors, ( selector ) => { + if ( selector.isRegistrySelector ) { + selector.registry = registry; + } + + return ( state, ...args ) => + selector( state.root, ...args ); + } ), + }, + store + ); + if ( options.resolvers ) { + const result = mapResolvers( + options.resolvers, + selectors, + store, + resolversCache + ); + resolvers = result.resolvers; + selectors = result.selectors; + } - const getSelectors = () => selectors; - const getActions = () => actions; - - // We have some modules monkey-patching the store object - // It's wrong to do so but until we refactor all of our effects to controls - // We need to keep the same "store" instance here. - store.__unstableOriginalGetState = store.getState; - store.getState = () => store.__unstableOriginalGetState().root; - - // Customize subscribe behavior to call listeners only on effective change, - // not on every dispatch. - const subscribe = - store && - ( ( listener ) => { - let lastState = store.__unstableOriginalGetState(); - store.subscribe( () => { - const state = store.__unstableOriginalGetState(); - const hasChanged = state !== lastState; - lastState = state; - - if ( hasChanged ) { - listener(); - } - } ); - } ); + const getSelectors = () => selectors; + const getActions = () => actions; + + // We have some modules monkey-patching the store object + // It's wrong to do so but until we refactor all of our effects to controls + // We need to keep the same "store" instance here. + store.__unstableOriginalGetState = store.getState; + store.getState = () => store.__unstableOriginalGetState().root; + + // Customize subscribe behavior to call listeners only on effective change, + // not on every dispatch. + const subscribe = + store && + ( ( listener ) => { + let lastState = store.__unstableOriginalGetState(); + store.subscribe( () => { + const state = store.__unstableOriginalGetState(); + const hasChanged = state !== lastState; + lastState = state; + + if ( hasChanged ) { + listener(); + } + } ); + } ); - // This can be simplified to just { subscribe, getSelectors, getActions } - // Once we remove the use function. - return { - reducer, - store, - actions, - selectors, - resolvers, - getSelectors, - getActions, - subscribe, + // This can be simplified to just { subscribe, getSelectors, getActions } + // Once we remove the use function. + return { + reducer, + store, + actions, + selectors, + resolvers, + getSelectors, + getActions, + subscribe, + }; + }, }; } /** * Creates a redux store for a namespace. * - * @param {string} key Unique namespace identifier. - * @param {Object} options Registered store options, with properties - * describing reducer, actions, selectors, and - * resolvers. - * @param {WPDataRegistry} registry Registry reference. + * @param {string} key Unique namespace identifier. + * @param {Object} options Registered store options, with properties + * describing reducer, actions, selectors, and + * resolvers. + * @param {import('../types').WPDataRegistry} registry Registry reference. * * @return {Object} Newly created redux store. */ -function createReduxStore( key, options, registry ) { +function instantiateReduxStore( key, options, registry ) { const controls = { ...options.controls, ...builtinControls, diff --git a/packages/data/src/namespace-store/metadata/actions.js b/packages/data/src/redux-store/metadata/actions.js similarity index 100% rename from packages/data/src/namespace-store/metadata/actions.js rename to packages/data/src/redux-store/metadata/actions.js diff --git a/packages/data/src/namespace-store/metadata/reducer.js b/packages/data/src/redux-store/metadata/reducer.js similarity index 100% rename from packages/data/src/namespace-store/metadata/reducer.js rename to packages/data/src/redux-store/metadata/reducer.js diff --git a/packages/data/src/namespace-store/metadata/selectors.js b/packages/data/src/redux-store/metadata/selectors.js similarity index 100% rename from packages/data/src/namespace-store/metadata/selectors.js rename to packages/data/src/redux-store/metadata/selectors.js diff --git a/packages/data/src/namespace-store/metadata/test/reducer.js b/packages/data/src/redux-store/metadata/test/reducer.js similarity index 100% rename from packages/data/src/namespace-store/metadata/test/reducer.js rename to packages/data/src/redux-store/metadata/test/reducer.js diff --git a/packages/data/src/namespace-store/metadata/test/selectors.js b/packages/data/src/redux-store/metadata/test/selectors.js similarity index 100% rename from packages/data/src/namespace-store/metadata/test/selectors.js rename to packages/data/src/redux-store/metadata/test/selectors.js diff --git a/packages/data/src/namespace-store/metadata/test/utils.js b/packages/data/src/redux-store/metadata/test/utils.js similarity index 100% rename from packages/data/src/namespace-store/metadata/test/utils.js rename to packages/data/src/redux-store/metadata/test/utils.js diff --git a/packages/data/src/namespace-store/metadata/utils.js b/packages/data/src/redux-store/metadata/utils.js similarity index 100% rename from packages/data/src/namespace-store/metadata/utils.js rename to packages/data/src/redux-store/metadata/utils.js diff --git a/packages/data/src/namespace-store/test/index.js b/packages/data/src/redux-store/test/index.js similarity index 100% rename from packages/data/src/namespace-store/test/index.js rename to packages/data/src/redux-store/test/index.js diff --git a/packages/data/src/registry.js b/packages/data/src/registry.js index fe3eb80d7efd93..669589d177cf25 100644 --- a/packages/data/src/registry.js +++ b/packages/data/src/registry.js @@ -1,13 +1,13 @@ /** * External dependencies */ -import { omit, without, mapValues } from 'lodash'; +import { omit, without, mapValues, isObject } from 'lodash'; import memize from 'memize'; /** * Internal dependencies */ -import createNamespace from './namespace-store'; +import createReduxStore from './redux-store'; import createCoreDataStore from './store'; /** @@ -74,18 +74,21 @@ export function createRegistry( storeConfigs = {}, parent = null ) { /** * Calls a selector given the current state and extra arguments. * - * @param {string} reducerKey Part of the state shape to register the - * selectors for. + * @param {string|import('./types').WPDataStoreDefinition} storeNameOrDefinition Unique namespace identifier for the store + * or the store definition. * * @return {*} The selector's returned value. */ - function select( reducerKey ) { - const store = stores[ reducerKey ]; + function select( storeNameOrDefinition ) { + const storeName = isObject( storeNameOrDefinition ) + ? storeNameOrDefinition.name + : storeNameOrDefinition; + const store = stores[ storeName ]; if ( store ) { return store.getSelectors(); } - return parent && parent.select( reducerKey ); + return parent && parent.select( storeName ); } const getResolveSelectors = memize( @@ -135,30 +138,33 @@ export function createRegistry( storeConfigs = {}, parent = null ) { * and modified so that they return promises that resolve to their eventual values, * after any resolvers have ran. * - * @param {string} reducerKey Part of the state shape to register the - * selectors for. + * @param {string|Object} storeName Unique namespace identifier for the store + * or the store definition. * * @return {Object} Each key of the object matches the name of a selector. */ - function __experimentalResolveSelect( reducerKey ) { - return getResolveSelectors( select( reducerKey ) ); + function __experimentalResolveSelect( storeName ) { + return getResolveSelectors( select( storeName ) ); } /** * Returns the available actions for a part of the state. * - * @param {string} reducerKey Part of the state shape to dispatch the - * action for. + * @param {string|import('./types').WPDataStoreDefinition} storeNameOrDefinition Unique namespace identifier for the store + * or the store definition. * * @return {*} The action's returned value. */ - function dispatch( reducerKey ) { - const store = stores[ reducerKey ]; + function dispatch( storeNameOrDefinition ) { + const storeName = isObject( storeNameOrDefinition ) + ? storeNameOrDefinition.name + : storeNameOrDefinition; + const store = stores[ storeName ]; if ( store ) { return store.getActions(); } - return parent && parent.dispatch( reducerKey ); + return parent && parent.dispatch( storeName ); } // @@ -196,6 +202,15 @@ export function createRegistry( storeConfigs = {}, parent = null ) { config.subscribe( globalListener ); } + /** + * Registers a new store. + * + * @param {import('./types').WPDataStore} store Store definition. + */ + function register( store ) { + registerGenericStore( store.name, store.instantiate( registry ) ); + } + let registry = { registerGenericStore, stores, @@ -205,24 +220,27 @@ export function createRegistry( storeConfigs = {}, parent = null ) { __experimentalResolveSelect, dispatch, use, + register, }; /** * Registers a standard `@wordpress/data` store. * - * @param {string} reducerKey Reducer key. + * @param {string} storeName Unique namespace identifier. * @param {Object} options Store description (reducer, actions, selectors, resolvers). * * @return {Object} Registered store object. */ - registry.registerStore = ( reducerKey, options ) => { + registry.registerStore = ( storeName, options ) => { if ( ! options.reducer ) { throw new TypeError( 'Must specify store reducer' ); } - const namespace = createNamespace( reducerKey, options, registry ); - registerGenericStore( reducerKey, namespace ); - return namespace.store; + const store = createReduxStore( storeName, options ).instantiate( + registry + ); + registerGenericStore( storeName, store ); + return store.store; }; // diff --git a/packages/data/src/store/index.js b/packages/data/src/store/index.js index 8310610cb59364..fa153fd9b640b5 100644 --- a/packages/data/src/store/index.js +++ b/packages/data/src/store/index.js @@ -1,10 +1,10 @@ function createCoreDataStore( registry ) { - const getCoreDataSelector = ( selectorName ) => ( reducerKey, ...args ) => { - return registry.select( reducerKey )[ selectorName ]( ...args ); + const getCoreDataSelector = ( selectorName ) => ( key, ...args ) => { + return registry.select( key )[ selectorName ]( ...args ); }; - const getCoreDataAction = ( actionName ) => ( reducerKey, ...args ) => { - return registry.dispatch( reducerKey )[ actionName ]( ...args ); + const getCoreDataAction = ( actionName ) => ( key, ...args ) => { + return registry.dispatch( key )[ actionName ]( ...args ); }; return { diff --git a/packages/data/src/test/registry.js b/packages/data/src/test/registry.js index ad4b47d308144c..b000f443563195 100644 --- a/packages/data/src/test/registry.js +++ b/packages/data/src/test/registry.js @@ -8,6 +8,7 @@ import { castArray, mapValues } from 'lodash'; */ import { createRegistry } from '../registry'; import { createRegistrySelector } from '../factory'; +import createReduxStore from '../redux-store'; jest.useFakeTimers(); @@ -551,6 +552,20 @@ describe( 'createRegistry', () => { ); } ); + it( 'should work with the store definition as param for select', () => { + const STORE_NAME = 'demo'; + const store = createReduxStore( STORE_NAME, { + reducer: ( state = 'OK' ) => state, + selectors: { + getValue: ( state ) => state, + }, + resolvers: {}, + } ); + registry.register( store ); + + expect( registry.select( store ).getValue() ).toBe( 'OK' ); + } ); + it( 'should run the registry selector from a non-registry selector', () => { const selector1 = () => 'result1'; const selector2 = createRegistrySelector( ( select ) => () => @@ -680,6 +695,27 @@ describe( 'createRegistry', () => { registry.dispatch( 'counter' ).increment( 4 ); // state = 5 expect( store.getState() ).toBe( 5 ); } ); + + it( 'should work with the store object as param for dispatch', async () => { + const STORE_NAME = 'demo'; + const store = registry.registerStore( STORE_NAME, { + reducer( state = 'OK', action ) { + if ( action.type === 'UPDATE' ) { + return 'UPDATED'; + } + return state; + }, + actions: { + update() { + return { type: 'UPDATE' }; + }, + }, + } ); + + expect( store.getState() ).toBe( 'OK' ); + await registry.dispatch( STORE_NAME ).update(); + expect( store.getState() ).toBe( 'UPDATED' ); + } ); } ); describe( 'use', () => { diff --git a/packages/data/src/types.d.ts b/packages/data/src/types.d.ts new file mode 100644 index 00000000000000..5c006762b0e21d --- /dev/null +++ b/packages/data/src/types.d.ts @@ -0,0 +1,32 @@ +export type WPDataFunctionOrGeneratorArray = Array< Function | Generator >; +export type WPDataFunctionArray = Array< Function >; + +export interface WPDataAttachedStore { + getSelectors: () => WPDataFunctionArray, + getActions: () => WPDataFunctionArray, + subscribe: (listener: () => void) => (() => void) +}; + +export interface WPDataStore { + /** + * Store Name + */ + name: string, + + /** + * Store configuration object. + */ + instantiate: (registry: WPDataRegistry) => WPDataAttachedStore, +}; + +export interface WPDataReduxStoreConfig { + reducer: ( state: any, action: any ) => any, + actions?: WPDataFunctionOrGeneratorArray, + resolvers?: WPDataFunctionOrGeneratorArray, + selectors?: WPDataFunctionArray, + controls?: WPDataFunctionArray, +} + +export interface WPDataRegistry { + register: ( store: WPDataStore ) => void, +} \ No newline at end of file diff --git a/packages/edit-navigation/src/store/index.js b/packages/edit-navigation/src/store/index.js index 78da40045a09b5..049f1785c9d205 100644 --- a/packages/edit-navigation/src/store/index.js +++ b/packages/edit-navigation/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, register } from '@wordpress/data'; /** * Internal dependencies @@ -15,7 +15,7 @@ import controls from './controls'; /** * Module Constants */ -const MODULE_KEY = 'core/edit-navigation'; +const STORE_NAME = 'core/edit-navigation'; /** * Block editor data store configuration. @@ -24,7 +24,7 @@ const MODULE_KEY = 'core/edit-navigation'; * * @type {Object} */ -export const storeConfig = { +const storeConfig = { reducer, controls, selectors, @@ -32,6 +32,13 @@ export const storeConfig = { actions, }; -const store = registerStore( MODULE_KEY, storeConfig ); +/** + * Store definition for the edit navigation namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, storeConfig ); -export default store; +register( store ); diff --git a/packages/edit-post/src/components/editor-initialization/listener-hooks.js b/packages/edit-post/src/components/editor-initialization/listener-hooks.js index 91af99219220d0..6b5b75b1155672 100644 --- a/packages/edit-post/src/components/editor-initialization/listener-hooks.js +++ b/packages/edit-post/src/components/editor-initialization/listener-hooks.js @@ -8,7 +8,7 @@ import { useEffect, useRef } from '@wordpress/element'; * Internal dependencies */ import { - STORE_KEY, + STORE_NAME, VIEW_AS_LINK_SELECTOR, VIEW_AS_PREVIEW_LINK_SELECTOR, } from '../../store/constants'; @@ -25,12 +25,12 @@ export const useBlockSelectionListener = ( postId ) => { hasBlockSelection: !! select( 'core/block-editor' ).getBlockSelectionStart(), - isEditorSidebarOpened: select( STORE_KEY ).isEditorSidebarOpened(), + isEditorSidebarOpened: select( STORE_NAME ).isEditorSidebarOpened(), } ), [ postId ] ); - const { openGeneralSidebar } = useDispatch( STORE_KEY ); + const { openGeneralSidebar } = useDispatch( STORE_NAME ); useEffect( () => { if ( ! isEditorSidebarOpened ) { diff --git a/packages/edit-post/src/components/editor-initialization/test/listener-hooks.js b/packages/edit-post/src/components/editor-initialization/test/listener-hooks.js index df53ba815dd575..853d2672431897 100644 --- a/packages/edit-post/src/components/editor-initialization/test/listener-hooks.js +++ b/packages/edit-post/src/components/editor-initialization/test/listener-hooks.js @@ -15,7 +15,7 @@ import { useBlockSelectionListener, useUpdatePostLinkListener, } from '../listener-hooks'; -import { STORE_KEY } from '../../../store/constants'; +import { STORE_NAME } from '../../../store/constants'; describe( 'listener hook tests', () => { const mockStores = { @@ -28,7 +28,7 @@ describe( 'listener hook tests', () => { 'core/viewport': { isViewportMatch: jest.fn(), }, - [ STORE_KEY ]: { + [ STORE_NAME ]: { isEditorSidebarOpened: jest.fn(), openGeneralSidebar: jest.fn(), closeGeneralSidebar: jest.fn(), @@ -78,19 +78,19 @@ describe( 'listener hook tests', () => { } ); describe( 'useBlockSelectionListener', () => { it( 'does nothing when editor sidebar is not open', () => { - setMockReturnValue( STORE_KEY, 'isEditorSidebarOpened', false ); + setMockReturnValue( STORE_NAME, 'isEditorSidebarOpened', false ); act( () => { renderComponent( useBlockSelectionListener, 10 ); } ); expect( - getSpyedFunction( STORE_KEY, 'isEditorSidebarOpened' ) + getSpyedFunction( STORE_NAME, 'isEditorSidebarOpened' ) ).toHaveBeenCalled(); expect( - getSpyedFunction( STORE_KEY, 'openGeneralSidebar' ) + getSpyedFunction( STORE_NAME, 'openGeneralSidebar' ) ).toHaveBeenCalledTimes( 0 ); } ); it( 'opens block sidebar if block is selected', () => { - setMockReturnValue( STORE_KEY, 'isEditorSidebarOpened', true ); + setMockReturnValue( STORE_NAME, 'isEditorSidebarOpened', true ); setMockReturnValue( 'core/block-editor', 'getBlockSelectionStart', @@ -100,11 +100,11 @@ describe( 'listener hook tests', () => { renderComponent( useBlockSelectionListener, 10 ); } ); expect( - getSpyedFunction( STORE_KEY, 'openGeneralSidebar' ) + getSpyedFunction( STORE_NAME, 'openGeneralSidebar' ) ).toHaveBeenCalledWith( 'edit-post/block' ); } ); it( 'opens document sidebar if block is not selected', () => { - setMockReturnValue( STORE_KEY, 'isEditorSidebarOpened', true ); + setMockReturnValue( STORE_NAME, 'isEditorSidebarOpened', true ); setMockReturnValue( 'core/block-editor', 'getBlockSelectionStart', @@ -114,7 +114,7 @@ describe( 'listener hook tests', () => { renderComponent( useBlockSelectionListener, 10 ); } ); expect( - getSpyedFunction( STORE_KEY, 'openGeneralSidebar' ) + getSpyedFunction( STORE_NAME, 'openGeneralSidebar' ) ).toHaveBeenCalledWith( 'edit-post/document' ); } ); } ); diff --git a/packages/edit-post/src/index.js b/packages/edit-post/src/index.js index a83aeb241d4b48..0e0f3d8399a09b 100644 --- a/packages/edit-post/src/index.js +++ b/packages/edit-post/src/index.js @@ -6,7 +6,6 @@ import '@wordpress/block-editor'; import '@wordpress/editor'; import '@wordpress/keyboard-shortcuts'; import '@wordpress/reusable-blocks'; -import '@wordpress/viewport'; import '@wordpress/notices'; import { registerCoreBlocks, diff --git a/packages/edit-post/src/index.native.js b/packages/edit-post/src/index.native.js index 93502e3701d091..6d09caa3d83094 100644 --- a/packages/edit-post/src/index.native.js +++ b/packages/edit-post/src/index.native.js @@ -2,7 +2,6 @@ * WordPress dependencies */ import '@wordpress/core-data'; -import '@wordpress/viewport'; import '@wordpress/notices'; import '@wordpress/format-library'; import '@wordpress/reusable-blocks'; diff --git a/packages/edit-post/src/store/constants.js b/packages/edit-post/src/store/constants.js index d3c02c71f312ee..115401a8f46639 100644 --- a/packages/edit-post/src/store/constants.js +++ b/packages/edit-post/src/store/constants.js @@ -3,7 +3,7 @@ * * @type {string} */ -export const STORE_KEY = 'core/edit-post'; +export const STORE_NAME = 'core/edit-post'; /** * CSS selector string for the admin bar view post link anchor tag. diff --git a/packages/edit-post/src/store/index.js b/packages/edit-post/src/store/index.js index 10005997a7cb05..7d08516f251a42 100644 --- a/packages/edit-post/src/store/index.js +++ b/packages/edit-post/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, registerStore } from '@wordpress/data'; /** * Internal dependencies @@ -10,15 +10,25 @@ import reducer from './reducer'; import applyMiddlewares from './middlewares'; import * as actions from './actions'; import * as selectors from './selectors'; -import { STORE_KEY } from './constants'; +import { STORE_NAME } from './constants'; -const store = registerStore( STORE_KEY, { +const storeConfig = { reducer, actions, selectors, persist: [ 'preferences' ], -} ); +}; -applyMiddlewares( store ); +/** + * Store definition for the edit post namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, storeConfig ); -export default store; +// Ideally we use register instead of register store. +// We shouuld be able to make the switch once we remove the effects. +const instantiatedStore = registerStore( STORE_NAME, storeConfig ); +applyMiddlewares( instantiatedStore ); diff --git a/packages/edit-site/src/store/constants.js b/packages/edit-site/src/store/constants.js index 27b051950e603b..174341a5cb02ae 100644 --- a/packages/edit-site/src/store/constants.js +++ b/packages/edit-site/src/store/constants.js @@ -3,4 +3,4 @@ * * @type {string} */ -export const STORE_KEY = 'core/edit-site'; +export const STORE_NAME = 'core/edit-site'; diff --git a/packages/edit-site/src/store/index.js b/packages/edit-site/src/store/index.js index fa012273201cde..25a90fabe0aaa6 100644 --- a/packages/edit-site/src/store/index.js +++ b/packages/edit-site/src/store/index.js @@ -11,10 +11,10 @@ import reducer from './reducer'; import * as actions from './actions'; import * as selectors from './selectors'; import controls from './controls'; -import { STORE_KEY } from './constants'; +import { STORE_NAME } from './constants'; export default function registerEditSiteStore( initialState ) { - const store = registerStore( STORE_KEY, { + const store = registerStore( STORE_NAME, { reducer, actions, selectors, diff --git a/packages/edit-widgets/src/store/batch-processing/constants.js b/packages/edit-widgets/src/store/batch-processing/constants.js index 0ad0691c43a463..56c0bbe4fb1e89 100644 --- a/packages/edit-widgets/src/store/batch-processing/constants.js +++ b/packages/edit-widgets/src/store/batch-processing/constants.js @@ -1,7 +1,7 @@ /** * Module Constants */ -export const MODULE_KEY = 'core/__experimental-batch-processing'; +export const STORE_NAME = 'core/__experimental-batch-processing'; export const BATCH_MAX_SIZE = 20; diff --git a/packages/edit-widgets/src/store/batch-processing/controls.js b/packages/edit-widgets/src/store/batch-processing/controls.js index 431fc1a49bf941..a9314a5ecaf700 100644 --- a/packages/edit-widgets/src/store/batch-processing/controls.js +++ b/packages/edit-widgets/src/store/batch-processing/controls.js @@ -6,7 +6,7 @@ import { createRegistryControl } from '@wordpress/data'; /** * Internal dependencies */ -import { MODULE_KEY, STATE_ERROR } from './constants'; +import { STORE_NAME, STATE_ERROR } from './constants'; /** * Calls a selector using chosen registry. @@ -58,25 +58,25 @@ export function enqueueItemAndAutocommit( queue, context, item ) { const controls = { SELECT: createRegistryControl( ( registry ) => ( { selectorName, args } ) => { - return registry.select( MODULE_KEY )[ selectorName ]( ...args ); + return registry.select( STORE_NAME )[ selectorName ]( ...args ); } ), DISPATCH: createRegistryControl( ( registry ) => ( { actionName, args } ) => { - return registry.dispatch( MODULE_KEY )[ actionName ]( ...args ); + return registry.dispatch( STORE_NAME )[ actionName ]( ...args ); } ), ENQUEUE_ITEM_AND_AUTOCOMMIT: createRegistryControl( ( registry ) => async ( { queue, context, item } ) => { const { itemId } = await registry - .dispatch( MODULE_KEY ) + .dispatch( STORE_NAME ) .enqueueItem( queue, context, item ); // @TODO autocommit when batch size exceeds the maximum or n milliseconds passes const batch = await registry - .dispatch( MODULE_KEY ) + .dispatch( STORE_NAME ) .processBatch( queue, context ); if ( batch.state === STATE_ERROR ) { @@ -92,12 +92,12 @@ const controls = { const { transactions, queue } = batch; const transaction = transactions[ transactionId ]; const processor = registry - .select( MODULE_KEY ) + .select( STORE_NAME ) .getProcessor( queue ); if ( ! processor ) { throw new Error( `There is no batch processor registered for "${ queue }" queue. ` + - `Register one by dispatching registerProcessor() action on ${ MODULE_KEY } store.` + `Register one by dispatching registerProcessor() action on ${ STORE_NAME } store.` ); } const itemIds = transaction.items.map( ( { id } ) => id ); diff --git a/packages/edit-widgets/src/store/batch-processing/index.js b/packages/edit-widgets/src/store/batch-processing/index.js index c2319d7b58a688..c50ae697ed9985 100644 --- a/packages/edit-widgets/src/store/batch-processing/index.js +++ b/packages/edit-widgets/src/store/batch-processing/index.js @@ -10,7 +10,7 @@ import * as actions from './actions'; import reducer from './reducer'; import controls from './controls'; import * as selectors from './selectors'; -import { MODULE_KEY } from './constants'; +import { STORE_NAME } from './constants'; /** * Block editor data store configuration. @@ -19,13 +19,13 @@ import { MODULE_KEY } from './constants'; * * @type {Object} */ -export const storeConfig = { +const storeConfig = { actions, reducer, controls, selectors, }; -const store = registerStore( MODULE_KEY, storeConfig ); +const store = registerStore( STORE_NAME, storeConfig ); export default store; diff --git a/packages/edit-widgets/src/store/index.js b/packages/edit-widgets/src/store/index.js index 06b847a9d2575a..bdbf487125e33f 100644 --- a/packages/edit-widgets/src/store/index.js +++ b/packages/edit-widgets/src/store/index.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import apiFetch from '@wordpress/api-fetch'; -import { registerStore } from '@wordpress/data'; +import { createReduxStore, register } from '@wordpress/data'; /** * Internal dependencies @@ -17,7 +17,7 @@ import './batch-support'; /** * Module Constants */ -const MODULE_KEY = 'core/edit-widgets'; +const STORE_NAME = 'core/edit-widgets'; /** * Block editor data store configuration. @@ -26,7 +26,7 @@ const MODULE_KEY = 'core/edit-widgets'; * * @type {Object} */ -export const storeConfig = { +const storeConfig = { reducer, controls, selectors, @@ -34,7 +34,16 @@ export const storeConfig = { actions, }; -const store = registerStore( MODULE_KEY, storeConfig ); +/** + * Store definition for the edit widgets namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, storeConfig ); + +register( store ); // This package uses a few in-memory post types as wrappers for convenience. // This middleware prevents any network requests related to these types as they are @@ -46,5 +55,3 @@ apiFetch.use( function ( options, next ) { return next( options ); } ); - -export default store; diff --git a/packages/editor/package.json b/packages/editor/package.json index e57318ca515d00..9044cf8baf4fa4 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -54,7 +54,6 @@ "@wordpress/rich-text": "file:../rich-text", "@wordpress/server-side-render": "file:../server-side-render", "@wordpress/url": "file:../url", - "@wordpress/viewport": "file:../viewport", "@wordpress/wordcount": "file:../wordcount", "classnames": "^2.2.5", "lodash": "^4.17.19", diff --git a/packages/editor/src/index.js b/packages/editor/src/index.js index 5e119148adb1de..0a58cd215cd754 100644 --- a/packages/editor/src/index.js +++ b/packages/editor/src/index.js @@ -8,17 +8,15 @@ import '@wordpress/keyboard-shortcuts'; import '@wordpress/notices'; import '@wordpress/reusable-blocks'; import '@wordpress/rich-text'; -import '@wordpress/viewport'; /** * Internal dependencies */ -import './store'; import './hooks'; +export { storeConfig, store } from './store'; export * from './components'; export * from './utils'; -export { storeConfig } from './store'; /* * Backward compatibility diff --git a/packages/editor/src/index.native.js b/packages/editor/src/index.native.js index 97a922ba6423e9..d3d3d52c24cee3 100644 --- a/packages/editor/src/index.native.js +++ b/packages/editor/src/index.native.js @@ -9,8 +9,8 @@ import '@wordpress/rich-text'; /** * Internal dependencies */ -import './store'; import './hooks'; +export { store } from './store'; export * from './components'; export * from './utils'; diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index f522b46a6e9bbd..51eba62c14505e 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -15,7 +15,7 @@ import { parse, synchronizeBlocksWithTemplate } from '@wordpress/blocks'; * Internal dependencies */ import { - STORE_KEY, + STORE_NAME, POST_UPDATE_TRANSACTION_ID, TRASH_POST_NOTICE_ID, } from './constants'; @@ -118,7 +118,7 @@ export function* resetAutosave( newAutosave ) { plugin: 'Gutenberg', } ); - const postId = yield controls.select( STORE_KEY, 'getCurrentPostId' ); + const postId = yield controls.select( STORE_NAME, 'getCurrentPostId' ); yield controls.dispatch( 'core', 'receiveAutosaves', postId, newAutosave ); return { type: '__INERT__' }; @@ -192,7 +192,7 @@ export function setupEditorState( post ) { * @yield {Object} Action object or control. */ export function* editPost( edits, options ) { - const { id, type } = yield controls.select( STORE_KEY, 'getCurrentPost' ); + const { id, type } = yield controls.select( STORE_NAME, 'getCurrentPost' ); yield controls.dispatch( 'core', 'editEntityRecord', @@ -225,20 +225,23 @@ export function __experimentalOptimisticUpdatePost( edits ) { * @param {Object} options */ export function* savePost( options = {} ) { - if ( ! ( yield controls.select( STORE_KEY, 'isEditedPostSaveable' ) ) ) { + if ( ! ( yield controls.select( STORE_NAME, 'isEditedPostSaveable' ) ) ) { return; } let edits = { - content: yield controls.select( STORE_KEY, 'getEditedPostContent' ), + content: yield controls.select( STORE_NAME, 'getEditedPostContent' ), }; if ( ! options.isAutosave ) { - yield controls.dispatch( STORE_KEY, 'editPost', edits, { + yield controls.dispatch( STORE_NAME, 'editPost', edits, { undoIgnore: true, } ); } yield __experimentalRequestPostUpdateStart( options ); - const previousRecord = yield controls.select( STORE_KEY, 'getCurrentPost' ); + const previousRecord = yield controls.select( + STORE_NAME, + 'getCurrentPost' + ); edits = { id: previousRecord.id, ...( yield controls.select( @@ -282,7 +285,7 @@ export function* savePost( options = {} ) { } } else { const updatedRecord = yield controls.select( - STORE_KEY, + STORE_NAME, 'getCurrentPost' ); const args = getNotificationArgumentsForSaveSuccess( { @@ -317,9 +320,9 @@ export function* savePost( options = {} ) { * Action generator for handling refreshing the current post. */ export function* refreshPost() { - const post = yield controls.select( STORE_KEY, 'getCurrentPost' ); + const post = yield controls.select( STORE_NAME, 'getCurrentPost' ); const postTypeSlug = yield controls.select( - STORE_KEY, + STORE_NAME, 'getCurrentPostType' ); const postType = yield controls.resolveSelect( @@ -334,7 +337,7 @@ export function* refreshPost() { `/wp/v2/${ postType.rest_base }/${ post.id }` + `?context=edit&_timestamp=${ Date.now() }`, } ); - yield controls.dispatch( STORE_KEY, 'resetPost', newPost ); + yield controls.dispatch( STORE_NAME, 'resetPost', newPost ); } /** @@ -342,7 +345,7 @@ export function* refreshPost() { */ export function* trashPost() { const postTypeSlug = yield controls.select( - STORE_KEY, + STORE_NAME, 'getCurrentPostType' ); const postType = yield controls.resolveSelect( @@ -356,13 +359,13 @@ export function* trashPost() { TRASH_POST_NOTICE_ID ); try { - const post = yield controls.select( STORE_KEY, 'getCurrentPost' ); + const post = yield controls.select( STORE_NAME, 'getCurrentPost' ); yield apiFetch( { path: `/wp/v2/${ postType.rest_base }/${ post.id }`, method: 'DELETE', } ); - yield controls.dispatch( STORE_KEY, 'savePost' ); + yield controls.dispatch( STORE_NAME, 'savePost' ); } catch ( error ) { yield controls.dispatch( 'core/notices', @@ -382,20 +385,23 @@ export function* trashPost() { */ export function* autosave( { local = false, ...options } = {} ) { if ( local ) { - const post = yield controls.select( STORE_KEY, 'getCurrentPost' ); - const isPostNew = yield controls.select( STORE_KEY, 'isEditedPostNew' ); + const post = yield controls.select( STORE_NAME, 'getCurrentPost' ); + const isPostNew = yield controls.select( + STORE_NAME, + 'isEditedPostNew' + ); const title = yield controls.select( - STORE_KEY, + STORE_NAME, 'getEditedPostAttribute', 'title' ); const content = yield controls.select( - STORE_KEY, + STORE_NAME, 'getEditedPostAttribute', 'content' ); const excerpt = yield controls.select( - STORE_KEY, + STORE_NAME, 'getEditedPostAttribute', 'excerpt' ); @@ -408,7 +414,7 @@ export function* autosave( { local = false, ...options } = {} ) { excerpt, }; } else { - yield controls.dispatch( STORE_KEY, 'savePost', { + yield controls.dispatch( STORE_NAME, 'savePost', { isAutosave: true, ...options, } ); @@ -610,7 +616,7 @@ export function* resetEditorBlocks( blocks, options = {} ) { if ( __unstableShouldCreateUndoLevel !== false ) { const { id, type } = yield controls.select( - STORE_KEY, + STORE_NAME, 'getCurrentPost' ); const noChange = diff --git a/packages/editor/src/store/constants.js b/packages/editor/src/store/constants.js index 1946c19d75b80e..073efe20455410 100644 --- a/packages/editor/src/store/constants.js +++ b/packages/editor/src/store/constants.js @@ -11,7 +11,7 @@ export const EDIT_MERGE_PROPERTIES = new Set( [ 'meta' ] ); * * @type {string} */ -export const STORE_KEY = 'core/editor'; +export const STORE_NAME = 'core/editor'; export const POST_UPDATE_TRANSACTION_ID = 'post-update'; export const SAVE_POST_NOTICE_ID = 'SAVE_POST_NOTICE_ID'; diff --git a/packages/editor/src/store/index.js b/packages/editor/src/store/index.js index af10a60cf74369..9d4a0d6ad71881 100644 --- a/packages/editor/src/store/index.js +++ b/packages/editor/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, registerStore } from '@wordpress/data'; import { controls as dataControls } from '@wordpress/data-controls'; /** @@ -11,7 +11,7 @@ import reducer from './reducer'; import * as selectors from './selectors'; import * as actions from './actions'; import controls from './controls'; -import { STORE_KEY } from './constants'; +import { STORE_NAME } from './constants'; /** * Post editor data store configuration. @@ -30,9 +30,21 @@ export const storeConfig = { }, }; -const store = registerStore( STORE_KEY, { +/** + * Store definition for the editor namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { ...storeConfig, persist: [ 'preferences' ], } ); -export default store; +// Once we build a more generic persistence plugin that works across types of stores +// we'd be able to replace this with a register call. +registerStore( STORE_NAME, { + ...storeConfig, + persist: [ 'preferences' ], +} ); diff --git a/packages/editor/src/store/test/actions.js b/packages/editor/src/store/test/actions.js index 389b8993c91c90..90da7d94b3094f 100644 --- a/packages/editor/src/store/test/actions.js +++ b/packages/editor/src/store/test/actions.js @@ -9,7 +9,7 @@ import { controls } from '@wordpress/data'; */ import * as actions from '../actions'; import { - STORE_KEY, + STORE_NAME, TRASH_POST_NOTICE_ID, POST_UPDATE_TRANSACTION_ID, } from '../constants'; @@ -47,7 +47,7 @@ describe( 'Post generator actions', () => { reset( isAutosave ); const { value } = fulfillment.next(); expect( value ).toEqual( - controls.select( STORE_KEY, 'isEditedPostSaveable' ) + controls.select( STORE_NAME, 'isEditedPostSaveable' ) ); }, ], @@ -57,7 +57,7 @@ describe( 'Post generator actions', () => { () => { const { value } = fulfillment.next( true ); expect( value ).toEqual( - controls.select( STORE_KEY, 'getEditedPostContent' ) + controls.select( STORE_NAME, 'getEditedPostContent' ) ); }, ], @@ -69,7 +69,7 @@ describe( 'Post generator actions', () => { const edits = { content: currentPost().content }; const { value } = fulfillment.next( edits.content ); expect( value ).toEqual( - controls.dispatch( STORE_KEY, 'editPost', edits, { + controls.dispatch( STORE_NAME, 'editPost', edits, { undoIgnore: true, } ) ); @@ -93,7 +93,7 @@ describe( 'Post generator actions', () => { () => { const { value } = fulfillment.next(); expect( value ).toEqual( - controls.select( STORE_KEY, 'getCurrentPost' ) + controls.select( STORE_NAME, 'getCurrentPost' ) ); }, ], @@ -168,7 +168,7 @@ describe( 'Post generator actions', () => { () => { const { value } = fulfillment.next(); expect( value ).toEqual( - controls.select( STORE_KEY, 'getCurrentPost' ) + controls.select( STORE_NAME, 'getCurrentPost' ) ); }, ], @@ -294,7 +294,7 @@ describe( 'Post generator actions', () => { reset(); const { value } = fulfillment.next(); expect( value ).toEqual( - controls.select( STORE_KEY, 'getCurrentPostType' ) + controls.select( STORE_NAME, 'getCurrentPostType' ) ); } ); it( 'yields expected action for selecting the post type object', () => { @@ -320,7 +320,7 @@ describe( 'Post generator actions', () => { it( 'yields expected action for selecting the currentPost', () => { const { value } = fulfillment.next(); expect( value ).toEqual( - controls.select( STORE_KEY, 'getCurrentPost' ) + controls.select( STORE_NAME, 'getCurrentPost' ) ); } ); it( 'yields expected action object for the api fetch', () => { @@ -353,7 +353,7 @@ describe( 'Post generator actions', () => { rewind(); const { value } = fulfillment.next(); expect( value ).toEqual( - controls.dispatch( STORE_KEY, 'savePost' ) + controls.dispatch( STORE_NAME, 'savePost' ) ); } ); } ); @@ -366,13 +366,13 @@ describe( 'Post generator actions', () => { reset(); const { value } = fulfillment.next(); expect( value ).toEqual( - controls.select( STORE_KEY, 'getCurrentPost' ) + controls.select( STORE_NAME, 'getCurrentPost' ) ); } ); it( 'yields expected action for selecting the current post type', () => { const { value } = fulfillment.next( currentPost ); expect( value ).toEqual( - controls.select( STORE_KEY, 'getCurrentPostType' ) + controls.select( STORE_NAME, 'getCurrentPostType' ) ); } ); it( 'yields expected action for selecting the post type object', () => { @@ -394,7 +394,7 @@ describe( 'Post generator actions', () => { it( 'yields expected action for dispatching the reset of the post', () => { const { value } = fulfillment.next( currentPost ); expect( value ).toEqual( - controls.dispatch( STORE_KEY, 'resetPost', currentPost ) + controls.dispatch( STORE_NAME, 'resetPost', currentPost ) ); } ); } ); @@ -475,7 +475,7 @@ describe( 'Editor actions', () => { const fulfillment = actions.editPost( edits ); expect( fulfillment.next() ).toEqual( { done: false, - value: controls.select( STORE_KEY, 'getCurrentPost' ), + value: controls.select( STORE_NAME, 'getCurrentPost' ), } ); const post = { id: 1, type: 'post' }; expect( fulfillment.next( post ) ).toEqual( { diff --git a/packages/interface/package.json b/packages/interface/package.json index e58d53376914dc..bf410cf0f7dbd3 100644 --- a/packages/interface/package.json +++ b/packages/interface/package.json @@ -36,6 +36,7 @@ "@wordpress/i18n": "file:../i18n", "@wordpress/icons": "file:../icons", "@wordpress/plugins": "file:../plugins", + "@wordpress/viewport": "file:../viewport", "classnames": "^2.2.5", "lodash": "^4.17.19" }, diff --git a/packages/interface/src/components/complementary-area/index.js b/packages/interface/src/components/complementary-area/index.js index 56ad63c601e183..f35fcf9d14bc17 100644 --- a/packages/interface/src/components/complementary-area/index.js +++ b/packages/interface/src/components/complementary-area/index.js @@ -11,6 +11,7 @@ import { useDispatch, useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { check, starEmpty, starFilled } from '@wordpress/icons'; import { useEffect, useRef } from '@wordpress/element'; +import { store as viewportStore } from '@wordpress/viewport'; /** * Internal dependencies @@ -104,10 +105,8 @@ function ComplementaryArea( { isActive: _activeArea === identifier, isPinned: isItemPinned( scope, identifier ), activeArea: _activeArea, - isSmall: select( 'core/viewport' ).isViewportMatch( - '< medium' - ), - isLarge: select( 'core/viewport' ).isViewportMatch( 'large' ), + isSmall: select( viewportStore ).isViewportMatch( '< medium' ), + isLarge: select( viewportStore ).isViewportMatch( 'large' ), }; }, [ identifier, scope ] diff --git a/packages/interface/src/index.js b/packages/interface/src/index.js index 7b5bd2101b7195..cf6bfc074cc058 100644 --- a/packages/interface/src/index.js +++ b/packages/interface/src/index.js @@ -1,6 +1,2 @@ -/** - * Internal dependencies - */ -import './store'; - +export { store } from './store'; export * from './components'; diff --git a/packages/interface/src/store/constants.js b/packages/interface/src/store/constants.js index ad82e7c6a6d755..766ef5e1c88737 100644 --- a/packages/interface/src/store/constants.js +++ b/packages/interface/src/store/constants.js @@ -3,4 +3,4 @@ * * @type {string} */ -export const STORE_KEY = 'core/interface'; +export const STORE_NAME = 'core/interface'; diff --git a/packages/interface/src/store/index.js b/packages/interface/src/store/index.js index 12c723cd51b04e..6d0337997ae930 100644 --- a/packages/interface/src/store/index.js +++ b/packages/interface/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, registerStore } from '@wordpress/data'; /** * Internal dependencies @@ -9,13 +9,27 @@ import { registerStore } from '@wordpress/data'; import reducer from './reducer'; import * as actions from './actions'; import * as selectors from './selectors'; -import { STORE_KEY } from './constants'; +import { STORE_NAME } from './constants'; -const store = registerStore( STORE_KEY, { +/** + * Store definition for the interface namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { reducer, actions, selectors, persist: [ 'enableItems' ], } ); -export default store; +// Once we build a more generic persistence plugin that works across types of stores +// we'd be able to replace this with a register call. +registerStore( STORE_NAME, { + reducer, + actions, + selectors, + persist: [ 'enableItems' ], +} ); diff --git a/packages/keyboard-shortcuts/README.md b/packages/keyboard-shortcuts/README.md index c9726284d461e3..27d7432447bd12 100644 --- a/packages/keyboard-shortcuts/README.md +++ b/packages/keyboard-shortcuts/README.md @@ -16,6 +16,18 @@ _This package assumes that your code will run in an **ES2015+** environment. If +# **store** + +Store definition for the keyboard shortcuts namespace. + +_Related_ + +- + +_Type_ + +- `Object` + # **useShortcut** Attach a keyboard shortcut handler. diff --git a/packages/keyboard-shortcuts/src/index.js b/packages/keyboard-shortcuts/src/index.js index 9a738b710b2dab..a57718af9c566e 100644 --- a/packages/keyboard-shortcuts/src/index.js +++ b/packages/keyboard-shortcuts/src/index.js @@ -1,6 +1,2 @@ -/** - * Internal dependencies - */ -import './store'; - +export { store } from './store'; export { default as useShortcut } from './hooks/use-shortcut'; diff --git a/packages/keyboard-shortcuts/src/store/index.js b/packages/keyboard-shortcuts/src/store/index.js index aadabb955d7526..0f40e3f4d74829 100644 --- a/packages/keyboard-shortcuts/src/store/index.js +++ b/packages/keyboard-shortcuts/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, register } from '@wordpress/data'; /** * Internal dependencies @@ -10,8 +10,19 @@ import reducer from './reducer'; import * as actions from './actions'; import * as selectors from './selectors'; -export default registerStore( 'core/keyboard-shortcuts', { +const STORE_NAME = 'core/keyboard-shortcuts'; + +/** + * Store definition for the keyboard shortcuts namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { reducer, actions, selectors, } ); + +register( store ); diff --git a/packages/notices/src/index.js b/packages/notices/src/index.js index a7ff64df3ef2a3..33b78d5a1d117e 100644 --- a/packages/notices/src/index.js +++ b/packages/notices/src/index.js @@ -1,4 +1 @@ -/** - * Internal dependencies - */ -import './store'; +export { store } from './store'; diff --git a/packages/notices/src/store/index.js b/packages/notices/src/store/index.js index 22a70e02ebb903..35c5e1d981b475 100644 --- a/packages/notices/src/store/index.js +++ b/packages/notices/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, register } from '@wordpress/data'; /** * Internal dependencies @@ -10,8 +10,19 @@ import reducer from './reducer'; import * as actions from './actions'; import * as selectors from './selectors'; -export default registerStore( 'core/notices', { +const STORE_NAME = 'core/notices'; + +/** + * Store definition for the notices namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { reducer, actions, selectors, } ); + +register( store ); diff --git a/packages/nux/src/index.js b/packages/nux/src/index.js index ffead08b9e4c2d..ffd4a5e8818828 100644 --- a/packages/nux/src/index.js +++ b/packages/nux/src/index.js @@ -3,11 +3,7 @@ */ import deprecated from '@wordpress/deprecated'; -/** - * Internal dependencies - */ -import './store'; - +export { store } from './store'; export { default as DotTip } from './components/dot-tip'; deprecated( 'wp.nux', { diff --git a/packages/nux/src/store/index.js b/packages/nux/src/store/index.js index 8f3e8af338dab2..ccd79e59ec1e16 100644 --- a/packages/nux/src/store/index.js +++ b/packages/nux/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, registerStore } from '@wordpress/data'; /** * Internal dependencies @@ -10,11 +10,27 @@ import reducer from './reducer'; import * as actions from './actions'; import * as selectors from './selectors'; -const store = registerStore( 'core/nux', { +const STORE_NAME = 'core/nux'; + +/** + * Store definition for the nux namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { reducer, actions, selectors, persist: [ 'preferences' ], } ); -export default store; +// Once we build a more generic persistence plugin that works across types of stores +// we'd be able to replace this with a register call. +registerStore( STORE_NAME, { + reducer, + actions, + selectors, + persist: [ 'preferences' ], +} ); diff --git a/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js b/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js index 6c88b881152b58..bd24b76261cc93 100644 --- a/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js +++ b/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-convert-button.js @@ -12,7 +12,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import { STORE_KEY } from '../../store/constants'; +import { store } from '../../store'; /** * Menu control to convert block(s) to reusable block. @@ -69,7 +69,7 @@ export default function ReusableBlockConvertButton( { const { __experimentalConvertBlocksToReusable: convertBlocksToReusable, - } = useDispatch( STORE_KEY ); + } = useDispatch( store ); const { createSuccessNotice, createErrorNotice } = useDispatch( 'core/notices' diff --git a/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-delete-button.js b/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-delete-button.js index bc59105d2e44b3..ac3abd0bb471cb 100644 --- a/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-delete-button.js +++ b/packages/reusable-blocks/src/components/reusable-blocks-menu-items/reusable-block-delete-button.js @@ -11,7 +11,7 @@ import { BlockSettingsMenuControls } from '@wordpress/block-editor'; /** * Internal dependencies */ -import { STORE_KEY } from '../../store/constants'; +import { store } from '../../store'; function ReusableBlockDeleteButton( { clientId } ) { const { isVisible, isDisabled, block } = useSelect( @@ -43,7 +43,7 @@ function ReusableBlockDeleteButton( { clientId } ) { const { __experimentalDeleteReusableBlock: deleteReusableBlock, - } = useDispatch( STORE_KEY ); + } = useDispatch( store ); const { createSuccessNotice, createErrorNotice } = useDispatch( 'core/notices' diff --git a/packages/reusable-blocks/src/index.js b/packages/reusable-blocks/src/index.js index 55ba8837aa1512..2faa13104e51ae 100644 --- a/packages/reusable-blocks/src/index.js +++ b/packages/reusable-blocks/src/index.js @@ -5,9 +5,5 @@ import '@wordpress/block-editor'; import '@wordpress/core-data'; import '@wordpress/notices'; -/** - * Internal dependencies - */ -import './store'; - +export { store } from './store'; export * from './components'; diff --git a/packages/reusable-blocks/src/index.native.js b/packages/reusable-blocks/src/index.native.js index 14c1977326fd52..2e29e8c63d8969 100644 --- a/packages/reusable-blocks/src/index.native.js +++ b/packages/reusable-blocks/src/index.native.js @@ -3,9 +3,5 @@ */ import '@wordpress/core-data'; -/** - * Internal dependencies - */ -import './store'; - +export { store } from './store'; export * from './components'; diff --git a/packages/reusable-blocks/src/store/constants.js b/packages/reusable-blocks/src/store/constants.js deleted file mode 100644 index 3563b7456c6c78..00000000000000 --- a/packages/reusable-blocks/src/store/constants.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Constant for the store module (or reducer) key. - * - * @type {string} - */ -export const STORE_KEY = 'core/reusable-blocks'; diff --git a/packages/reusable-blocks/src/store/index.js b/packages/reusable-blocks/src/store/index.js index b6b212ad968a88..46a38b67f8b8f7 100644 --- a/packages/reusable-blocks/src/store/index.js +++ b/packages/reusable-blocks/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, register } from '@wordpress/data'; /** * Internal dependencies @@ -10,18 +10,21 @@ import * as actions from './actions'; import controls from './controls'; import reducer from './reducer'; import * as selectors from './selectors'; -import { STORE_KEY } from './constants'; + +const STORE_NAME = 'core/reusable-blocks'; /** - * Data store configuration. + * Store definition for the reusable blocks namespace. * - * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#registerStore + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore * * @type {Object} */ -export default registerStore( STORE_KEY, { +export const store = createReduxStore( STORE_NAME, { actions, controls, reducer, selectors, } ); + +register( store ); diff --git a/packages/rich-text/README.md b/packages/rich-text/README.md index 339e08a8af31a7..766eb4566de490 100644 --- a/packages/rich-text/README.md +++ b/packages/rich-text/README.md @@ -302,6 +302,18 @@ _Returns_ - `Array`: An array of new values. +# **store** + +Store definition for the rich-text namespace. + +_Related_ + +- + +_Type_ + +- `Object` + # **toggleFormat** Toggles a format object to a Rich Text value at the current selection. diff --git a/packages/rich-text/src/index.js b/packages/rich-text/src/index.js index 0d78b652a0ffdf..18791abde00a10 100644 --- a/packages/rich-text/src/index.js +++ b/packages/rich-text/src/index.js @@ -1,8 +1,4 @@ -/** - * Internal dependencies - */ -import './store'; - +export { store } from './store'; export { applyFormat } from './apply-format'; export { concat } from './concat'; export { create } from './create'; diff --git a/packages/rich-text/src/store/index.js b/packages/rich-text/src/store/index.js index beaed276c2fd69..02b320b2a43b07 100644 --- a/packages/rich-text/src/store/index.js +++ b/packages/rich-text/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, register } from '@wordpress/data'; /** * Internal dependencies @@ -10,4 +10,19 @@ import reducer from './reducer'; import * as selectors from './selectors'; import * as actions from './actions'; -registerStore( 'core/rich-text', { reducer, selectors, actions } ); +const STORE_NAME = 'core/rich-text'; + +/** + * Store definition for the rich-text namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { + reducer, + selectors, + actions, +} ); + +register( store ); diff --git a/packages/side-effects.md b/packages/side-effects.md index c0e9c7ba07e52d..78bb144bdac98f 100644 --- a/packages/side-effects.md +++ b/packages/side-effects.md @@ -9,8 +9,8 @@ Here is an example: ```js import { registerStore } from '@wordpress/data'; -const store = registerStore( STORE_KEY, { - // ... +const store = registerStore( STORE_NAME, { + // ... } ); ``` @@ -22,7 +22,7 @@ However, if this were to happen inside of an `init` function that doesn't get ca import { registerStore } from '@wordpress/data'; export function init() { - const store = registerStore( STORE_KEY, { + const store = registerStore( STORE_NAME, { // ... } ); } @@ -85,4 +85,4 @@ If it has a few files with side effects, it can list them: } ``` -This allows the bundler to assume that only the modules that were declared have side effects, and *nothing else does*. Of course, this means that we need to be careful to include everything that *does* have side effects, or problems can arise in applications that make use of the package. +This allows the bundler to assume that only the modules that were declared have side effects, and _nothing else does_. Of course, this means that we need to be careful to include everything that _does_ have side effects, or problems can arise in applications that make use of the package. diff --git a/packages/viewport/README.md b/packages/viewport/README.md index 320f46daf8d431..ae3cc8dbe04d64 100644 --- a/packages/viewport/README.md +++ b/packages/viewport/README.md @@ -76,6 +76,18 @@ _Returns_ - `Function`: Higher-order component. +# **store** + +Store definition for the viewport namespace. + +_Related_ + +- + +_Type_ + +- `Object` + # **withViewportMatch** Higher-order component creator, creating a new component which renders with diff --git a/packages/viewport/src/index.js b/packages/viewport/src/index.js index b2faa967569480..8bb1166d60f649 100644 --- a/packages/viewport/src/index.js +++ b/packages/viewport/src/index.js @@ -1,9 +1,9 @@ /** * Internal dependencies */ -import './store'; import addDimensionsEventListener from './listener'; +export { store } from './store'; export { default as ifViewportMatches } from './if-viewport-matches'; export { default as withViewportMatch } from './with-viewport-match'; diff --git a/packages/viewport/src/listener.js b/packages/viewport/src/listener.js index 4d81e15cc3f31d..b87e1b7d3bc2aa 100644 --- a/packages/viewport/src/listener.js +++ b/packages/viewport/src/listener.js @@ -8,6 +8,11 @@ import { reduce, forEach, debounce, mapValues } from 'lodash'; */ import { dispatch } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store } from './store'; + const addDimensionsEventListener = ( breakpoints, operators ) => { /** * Callback invoked when media query state should be updated. Is invoked a @@ -16,7 +21,7 @@ const addDimensionsEventListener = ( breakpoints, operators ) => { const setIsMatching = debounce( () => { const values = mapValues( queries, ( query ) => query.matches ); - dispatch( 'core/viewport' ).setIsMatching( values ); + dispatch( store ).setIsMatching( values ); }, { leading: true } ); diff --git a/packages/viewport/src/listener.native.js b/packages/viewport/src/listener.native.js index 064ffbb81505dd..ec8bf2203d3e0f 100644 --- a/packages/viewport/src/listener.native.js +++ b/packages/viewport/src/listener.native.js @@ -9,6 +9,11 @@ import { Dimensions } from 'react-native'; */ import { dispatch } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store } from './store'; + const matchWidth = ( operator, breakpoint ) => { const { width } = Dimensions.get( 'window' ); if ( operator === 'max-width' ) { @@ -34,7 +39,7 @@ const addDimensionsEventListener = ( breakpoints, operators ) => { {} ); - dispatch( 'core/viewport' ).setIsMatching( matches ); + dispatch( store ).setIsMatching( matches ); }; Dimensions.addEventListener( 'change', setIsMatching ); diff --git a/packages/viewport/src/store/index.js b/packages/viewport/src/store/index.js index 88c7cba476165e..29f39dbccc1c16 100644 --- a/packages/viewport/src/store/index.js +++ b/packages/viewport/src/store/index.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { registerStore } from '@wordpress/data'; +import { createReduxStore, register } from '@wordpress/data'; /** * Internal dependencies @@ -10,8 +10,19 @@ import reducer from './reducer'; import * as actions from './actions'; import * as selectors from './selectors'; -export default registerStore( 'core/viewport', { +const STORE_NAME = 'core/viewport'; + +/** + * Store definition for the viewport namespace. + * + * @see https://github.com/WordPress/gutenberg/blob/master/packages/data/README.md#createReduxStore + * + * @type {Object} + */ +export const store = createReduxStore( STORE_NAME, { reducer, actions, selectors, } ); + +register( store ); diff --git a/packages/viewport/src/with-viewport-match.native.js b/packages/viewport/src/with-viewport-match.native.js index 983aa22e365f83..6ef490d0ff1d94 100644 --- a/packages/viewport/src/with-viewport-match.native.js +++ b/packages/viewport/src/with-viewport-match.native.js @@ -9,6 +9,11 @@ import { mapValues } from 'lodash'; import { createHigherOrderComponent } from '@wordpress/compose'; import { withSelect } from '@wordpress/data'; +/** + * Internal dependencies + */ +import { store } from './store'; + /** * Higher-order component creator, creating a new component which renders with * the given prop names, where the value passed to the underlying component is @@ -36,7 +41,7 @@ const withViewportMatch = ( queries ) => createHigherOrderComponent( withSelect( ( select ) => { return mapValues( queries, ( query ) => { - return select( 'core/viewport' ).isViewportMatch( query ); + return select( store ).isViewportMatch( query ); } ); } ), 'withViewportMatch'