-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gutenberg: Reset core resolvers on site change #29445
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export const setSelectedSiteId = selectedSiteId => ( { | ||
type: 'GUTENLYPSO_SELECTED_SITE_ID_SET', | ||
selectedSiteId, | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** | ||
* WordPress Dependencies | ||
*/ | ||
import { registerStore } from '@wordpress/data'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import reducer from './reducer'; | ||
import * as actions from './actions'; | ||
import * as selectors from './selectors'; | ||
|
||
const store = registerStore( 'gutenberg/calypso', { | ||
reducer, | ||
actions, | ||
selectors, | ||
} ); | ||
|
||
export default store; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/* eslint-disable wpcalypso/import-docblock */ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { combineReducers } from '@wordpress/data'; | ||
|
||
const selectedSiteId = ( state = null, action ) => | ||
'GUTENLYPSO_SELECTED_SITE_ID_SET' === action.type ? action.selectedSiteId : state; | ||
|
||
export default combineReducers( { selectedSiteId } ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const getSelectedSiteId = state => state.selectedSiteId; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,26 +34,34 @@ const addResetToRegistry = registry => { | |
window.gutenbergState = () => mapValues( registry.stores, ( { store } ) => store.getState() ); | ||
} | ||
|
||
const resettableStores = [ 'core/editor', 'core/notices' ]; | ||
|
||
const stores = []; | ||
return { | ||
registerStore( namespace, options ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @aduth @jsnajdr In other words, this function here allows me to reset There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason why the At that time, the I don't think that being able to fully reset the Fortunately, some support for resetting function resetStoreResolutions( registry, reducerKey ) {
const resolvers = registry.select( 'core/data' ).getCachedResolvers( reducerKey );
Object.entries( resolvers ).forEach( ( [ selectorName, resolversByArgs ] ) => {
resolversByArgs.forEach( ( _, args ) => {
registry.dispatch( 'core/data' ).invalidateResolution( reducerKey, selectorName, args );
} );
} );
} Then we can add a call to this new function to the reset() {
resettableStores.forEach( reducerKey => {
registry.stores[ reducerKey ].dispatch( { type: 'GUTENLYPSO_RESET' } );
resetStoreResolutions( registry, reducerKey );
} );
} This should reset everything on site change. There is just one race condition bug that remains: if a request for entities from site ID=1 is in flight, and we switch to site ID=2, then the response from site ID=2 will be received into store with site ID=2! The cache invalidation code in WordPress/gutenberg#10089 probably has a similar bug: it won't invalidate resolution for selector whose request is in flight. There can be "get a list" and "add to list" requests happening at the same time, and if their "issue request from client", "perform request on server" and "receive response on client" are performed in a certain order, the resulting state will miss the just-added entity. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Created an issue for tracking at WordPress/gutenberg#12984 |
||
let store; | ||
if ( -1 === resettableStores.indexOf( namespace ) ) { | ||
store = registry.registerStore( namespace, options ); | ||
} else { | ||
store = registry.registerStore( namespace, { | ||
...options, | ||
reducer: ( state, action ) => | ||
options.reducer( 'GUTENLYPSO_RESET' === action.type ? undefined : state, action ), | ||
} ); | ||
} | ||
const store = registry.registerStore( namespace, { | ||
...options, | ||
reducer: ( state, action ) => { | ||
if ( 'GUTENLYPSO_RESET' === action.type && namespace === action.namespace ) { | ||
debug( `Resetting ${ namespace } store` ); | ||
return options.reducer( undefined, action ); | ||
} | ||
return options.reducer( state, action ); | ||
}, | ||
} ); | ||
stores.push( store ); | ||
return store; | ||
}, | ||
reset() { | ||
stores.forEach( store => store.dispatch( { type: 'GUTENLYPSO_RESET' } ) ); | ||
reset( namespace ) { | ||
stores.forEach( store => store.dispatch( { type: 'GUTENLYPSO_RESET', namespace } ) ); | ||
}, | ||
resetCoreResolvers() { | ||
// @see https://github.com/WordPress/gutenberg/blob/e1092c0d0b75fe53ab57bc6c4cc9e32cb2e74e40/packages/data/src/resolvers-cache-middleware.js#L14-L34 | ||
const resolvers = registry.select( 'core/data' ).getCachedResolvers( 'core' ); | ||
debug( `Resetting core store resolvers: ${ Object.keys( resolvers ).toString() }` ); | ||
Object.entries( resolvers ).forEach( ( [ selectorName, resolversByArgs ] ) => { | ||
resolversByArgs.forEach( ( value, args ) => { | ||
registry.dispatch( 'core/data' ).invalidateResolution( 'core', selectorName, args ); | ||
} ); | ||
} ); | ||
}, | ||
}; | ||
}; | ||
|
@@ -63,12 +71,15 @@ const addResetToRegistry = registry => { | |
export const initGutenberg = once( ( userId, store ) => { | ||
debug( 'Starting Gutenberg editor initialization...' ); | ||
|
||
const registry = use( addResetToRegistry ); | ||
|
||
debug( 'Registering data plugins' ); | ||
const storageKey = 'WP_DATA_USER_' + userId; | ||
use( plugins.persistence, { storageKey: storageKey } ); | ||
use( plugins.controls ); | ||
|
||
const registry = use( addResetToRegistry ); | ||
debug( 'Initializing gutenberg/calypso store' ); | ||
require( 'gutenberg/editor/calypso-store' ); | ||
|
||
// We need to ensure that core-data is loaded after the data plugins have been registered. | ||
debug( 'Initializing core-data store' ); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat. :)