Skip to content

Commit

Permalink
Data: Implement atomic stores (#26866)
Browse files Browse the repository at this point in the history
Co-authored-by: Greg Ziółkowski <[email protected]>
Co-authored-by: Jon Surrell <[email protected]>
  • Loading branch information
3 people committed Nov 20, 2020
1 parent e7cb38c commit 99f95d7
Show file tree
Hide file tree
Showing 53 changed files with 2,136 additions and 615 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ playground/dist
.cache
*.tsbuildinfo

# Report generated from jest-junit
# Report generated from tests
test/native/junit.xml

# Local overrides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ Returns the raw representation of all the keyboard combinations of a given short

_Parameters_

- _state_ `Object`: Global state.
- _name_ `string`: Shortcut name.

_Returns_
Expand All @@ -25,8 +24,7 @@ Returns the shortcut names list for a given category name.

_Parameters_

- _state_ `Object`: Global state.
- _name_ `string`: Category name.
- _categoryName_ `string`: Category name.

_Returns_

Expand All @@ -38,7 +36,6 @@ Returns the aliases for a given shortcut name.

_Parameters_

- _state_ `Object`: Global state.
- _name_ `string`: Shortcut name.

_Returns_
Expand All @@ -51,7 +48,6 @@ Returns the shortcut description given its name.

_Parameters_

- _state_ `Object`: Global state.
- _name_ `string`: Shortcut name.

_Returns_
Expand All @@ -64,7 +60,6 @@ Returns the main key combination for a given shortcut name.

_Parameters_

- _state_ `Object`: Global state.
- _name_ `string`: Shortcut name.

_Returns_
Expand All @@ -77,7 +72,6 @@ Returns a string representing the main key combination for a given shortcut name

_Parameters_

- _state_ `Object`: Global state.
- _name_ `string`: Shortcut name.
- _representation_ (unknown type): Type of representation (display, raw, ariaLabel).

Expand All @@ -97,23 +91,19 @@ Returns an action object used to register a new keyboard shortcut.

_Parameters_

- _get_ `Function`: Atom resover.
- _set_ `Function`: Atom updater.
- _config_ `WPShortcutConfig`: Shortcut config.

_Returns_

- `Object`: action.

<a name="unregisterShortcut" href="#unregisterShortcut">#</a> **unregisterShortcut**

Returns an action object used to unregister a keyboard shortcut.

_Parameters_

- _get_ `Function`: get atom value.
- _set_ `Function`: set atom value.
- _name_ `string`: Shortcut name.

_Returns_

- `Object`: action.


<!-- END TOKEN(Autogenerated actions|../../../../packages/keyboard-shortcuts/src/store/actions.js) -->
6 changes: 6 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1793,6 +1793,12 @@
"markdown_source": "../packages/shortcode/README.md",
"parent": "packages"
},
{
"title": "@wordpress/stan",
"slug": "packages-stan",
"markdown_source": "../packages/stan/README.md",
"parent": "packages"
},
{
"title": "@wordpress/token-list",
"slug": "packages-token-list",
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"@wordpress/rich-text": "file:packages/rich-text",
"@wordpress/server-side-render": "file:packages/server-side-render",
"@wordpress/shortcode": "file:packages/shortcode",
"@wordpress/stan": "file:packages/stan",
"@wordpress/token-list": "file:packages/token-list",
"@wordpress/url": "file:packages/url",
"@wordpress/viewport": "file:packages/viewport",
Expand Down
26 changes: 14 additions & 12 deletions packages/block-directory/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ describe( 'selectors', () => {

describe( 'getNewBlockTypes', () => {
it( 'should retrieve the block types that are installed and in the post content', () => {
getNewBlockTypes.registry = {
select: jest.fn( () => ( { getBlocks: () => blockList } ) ),
};
getNewBlockTypes.__unstableGetSelect = jest.fn( () => ( {
getBlocks: () => blockList,
} ) );
const state = {
blockManagement: {
installedBlockTypes: [
Expand All @@ -106,9 +106,9 @@ describe( 'selectors', () => {
} );

it( 'should return an empty array if no blocks are used', () => {
getNewBlockTypes.registry = {
select: jest.fn( () => ( { getBlocks: () => [] } ) ),
};
getNewBlockTypes.__unstableGetSelect = jest.fn( () => ( {
getBlocks: () => [],
} ) );
const state = {
blockManagement: {
installedBlockTypes: [
Expand All @@ -124,9 +124,10 @@ describe( 'selectors', () => {

describe( 'getUnusedBlockTypes', () => {
it( 'should retrieve the block types that are installed but not used', () => {
getUnusedBlockTypes.registry = {
select: jest.fn( () => ( { getBlocks: () => blockList } ) ),
};
getUnusedBlockTypes.__unstableGetSelect = jest.fn( () => ( {
getBlocks: () => blockList,
} ) );

const state = {
blockManagement: {
installedBlockTypes: [
Expand All @@ -141,9 +142,10 @@ describe( 'selectors', () => {
} );

it( 'should return all block types if no blocks are used', () => {
getUnusedBlockTypes.registry = {
select: jest.fn( () => ( { getBlocks: () => [] } ) ),
};
getUnusedBlockTypes.__unstableGetSelect = jest.fn( () => ( {
getBlocks: () => [],
} ) );

const state = {
blockManagement: {
installedBlockTypes: [
Expand Down
1 change: 1 addition & 0 deletions packages/compose/src/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export { default as __experimentalUseDragging } from './hooks/use-dragging';
export { default as useInstanceId } from './hooks/use-instance-id';
export { default as useKeyboardShortcut } from './hooks/use-keyboard-shortcut';
export { default as useMediaQuery } from './hooks/use-media-query';
export { default as usePrevious } from './hooks/use-previous';
export { default as useReducedMotion } from './hooks/use-reduced-motion';
export { default as useViewportMatch } from './hooks/use-viewport-match';
export { default as useAsyncList } from './hooks/use-async-list';
Expand Down
1 change: 1 addition & 0 deletions packages/data/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@wordpress/is-shallow-equal": "file:../is-shallow-equal",
"@wordpress/priority-queue": "file:../priority-queue",
"@wordpress/redux-routine": "file:../redux-routine",
"@wordpress/stan": "file:../stan",
"equivalent-key-map": "^0.2.2",
"is-promise": "^4.0.0",
"lodash": "^4.17.19",
Expand Down
83 changes: 83 additions & 0 deletions packages/data/src/atomic-store/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* External dependencies
*/
import { mapValues } from 'lodash';

/**
* WordPress dependencies
*/
import { createDerivedAtom } from '@wordpress/stan';

/**
* @typedef {import("../types").WPDataAtomicStoreConfig} WPDataAtomicStoreConfig
*/
/**
* @typedef {import("../types").WPDataStore} WPDataStore
*/
/**
* @template T
* @typedef {import('@wordpress/stan/src/types').WPAtom<T>} WPAtom
*/
/**
* @template T
* @typedef {import('@wordpress/stan/src/types').WPAtomFamilyItem<T>} WPAtomFamilyItem
*/

/**
*
* @param {string} name Store name.
* @param {WPDataAtomicStoreConfig} config Atomic store config.
* @return {WPDataStore} Store.
*/
export default function createAtomicStore( name, config ) {
return {
name,
instantiate: ( registry ) => {
const selectors = mapValues( config.selectors, ( atomSelector ) => {
return ( /** @type {any[]} **/ ...args ) => {
const get = registry.__internalGetAtomResolver()
? registry.__internalGetAtomResolver()
: (
/** @type {WPAtom<any>|WPAtomFamilyItem<any>} **/ atom
) => registry.__internalGetAtomRegistry().get( atom );
return atomSelector( ...args )( { get } );
};
} );

const actions = mapValues( config.actions, ( atomAction ) => {
return ( /** @type {any[]} **/ ...args ) => {
return atomAction( ...args )( {
get: ( atomCreator ) =>
registry
.__internalGetAtomRegistry()
.get( atomCreator ),
set: ( atomCreator, value ) =>
registry
.__internalGetAtomRegistry()
.set( atomCreator, value ),
} );
};
} );

return {
__internalIsAtomic: true,
getSelectors: () => selectors,
getActions: () => actions,

// Subscribing to the root atoms allows us
// To refresh the data when all root selector change.
subscribe: ( listener ) => {
const atom = createDerivedAtom( ( { get } ) => {
config.rootAtoms.forEach( ( subatom ) =>
get( subatom )
);
} );

return registry
.__internalGetAtomRegistry()
.subscribe( atom, listener );
},
};
},
};
}
Loading

0 comments on commit 99f95d7

Please sign in to comment.