Skip to content

Commit

Permalink
Data: Create registry selector with self-contained registry proxying (#…
Browse files Browse the repository at this point in the history
…16692)

* Data: Create registry selector with self-contained registry proxying

* Editor: Fix tests that relied on registry selectors being higher order.

* Data: Add typedef import reference for WPDataRegistry

* Data: Omit removed registry argument from mapSelectors
  • Loading branch information
aduth authored Jul 31, 2019
1 parent e4b1337 commit 1a929eb
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 21 deletions.
29 changes: 27 additions & 2 deletions packages/data/src/factory.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
/**
* Internal dependencies
*/
import defaultRegistry from './default-registry';

/**
* @typedef {import('./registry').WPDataRegistry} WPDataRegistry
*/

/**
* Mark a selector as a registry selector.
*
Expand All @@ -6,9 +15,25 @@
* @return {function} marked registry selector.
*/
export function createRegistrySelector( registrySelector ) {
registrySelector.isRegistrySelector = true;
const selector = ( ...args ) => registrySelector( selector.registry.select )( ...args );

/**
* Flag indicating to selector registration mapping that the selector should
* be mapped as a registry selector.
*
* @type {boolean}
*/
selector.isRegistrySelector = true;

/**
* Registry on which to call `select`, stubbed for non-standard usage to
* use the default registry.
*
* @type {WPDataRegistry}
*/
selector.registry = defaultRegistry;

return registrySelector;
return selector;
}

/**
Expand Down
26 changes: 8 additions & 18 deletions packages/data/src/namespace-store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,12 @@ export default function createNamespace( key, options, registry ) {
...mapValues( metadataSelectors, ( selector ) => ( state, ...args ) => selector( state.metadata, ...args ) ),
...mapValues( options.selectors, ( selector ) => {
if ( selector.isRegistrySelector ) {
const mappedSelector = ( reg ) => ( state, ...args ) => {
return selector( reg )( state.root, ...args );
};
mappedSelector.isRegistrySelector = selector.isRegistrySelector;
return mappedSelector;
selector.registry = registry;
}

return ( state, ...args ) => selector( state.root, ...args );
} ),
}, store, registry );
}, store );
if ( options.resolvers ) {
const result = mapResolvers( options.resolvers, selectors, store );
resolvers = result.resolvers;
Expand Down Expand Up @@ -152,21 +148,15 @@ function createReduxStore( key, options, registry ) {
/**
* Maps selectors to a store.
*
* @param {Object} selectors Selectors to register. Keys will be used as
* the public facing API. Selectors will get
* passed the state as first argument.
* @param {Object} store The store to which the selectors should be
* mapped.
* @param {WPDataRegistry} registry Registry reference.
* @param {Object} selectors Selectors to register. Keys will be used as the
* public facing API. Selectors will get passed the
* state as first argument.
* @param {Object} store The store to which the selectors should be mapped.
*
* @return {Object} Selectors mapped to the provided store.
*/
function mapSelectors( selectors, store, registry ) {
const createStateSelector = ( registeredSelector ) => {
const registrySelector = registeredSelector.isRegistrySelector ?
registeredSelector( registry.select ) :
registeredSelector;

function mapSelectors( selectors, store ) {
const createStateSelector = ( registrySelector ) => {
const selector = function runSelector() {
// This function is an optimized implementation of:
//
Expand Down
32 changes: 32 additions & 0 deletions packages/data/src/test/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,38 @@ describe( 'createRegistry', () => {

expect( registry.select( 'reducer2' ).selector2() ).toEqual( 'result1' );
} );

it( 'should run the registry selector from a non-registry selector', () => {
const selector1 = () => 'result1';
const selector2 = createRegistrySelector( ( select ) => () =>
select( 'reducer1' ).selector1()
);
const selector3 = () => selector2();
registry.registerStore( 'reducer1', {
reducer: () => 'state1',
selectors: {
selector1,
},
} );
registry.registerStore( 'reducer2', {
reducer: () => 'state1',
selectors: {
selector2,
selector3,
},
} );

expect( registry.select( 'reducer2' ).selector3() ).toEqual( 'result1' );
} );

it( 'gracefully stubs select on selector calls', () => {
const selector = createRegistrySelector( ( select ) => () => select );

const maybeSelect = selector();

expect( maybeSelect ).toEqual( expect.any( Function ) );
expect( maybeSelect() ).toEqual( expect.any( Object ) );
} );
} );

describe( 'subscribe', () => {
Expand Down
7 changes: 6 additions & 1 deletion packages/editor/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const {
isCurrentPostScheduled,
isEditedPostPublishable,
isEditedPostSaveable,
isEditedPostAutosaveable: isEditedPostAutosaveableRegistrySelector,
isEditedPostAutosaveable: _isEditedPostAutosaveableRegistrySelector,
isEditedPostEmpty,
isEditedPostBeingScheduled,
isEditedPostDateFloating,
Expand All @@ -71,9 +71,14 @@ const {

describe( 'selectors', () => {
let cachedSelectors;
let isEditedPostAutosaveableRegistrySelector;

beforeAll( () => {
cachedSelectors = filter( selectors, ( selector ) => selector.clear );
isEditedPostAutosaveableRegistrySelector = ( select ) => {
_isEditedPostAutosaveableRegistrySelector.registry = { select };
return _isEditedPostAutosaveableRegistrySelector;
};
} );

beforeEach( () => {
Expand Down

0 comments on commit 1a929eb

Please sign in to comment.