Skip to content
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

Core Data: Fixes necessary for converting to TypeScript #39211

Merged
merged 2 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/reference-guides/data/data-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ _Parameters_
- _state_ `Object`: State tree.
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _recordId_ `number`: Record ID.
- _recordId_ `number|string`: Record ID.

_Returns_

Expand Down
2 changes: 1 addition & 1 deletion packages/core-data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ _Parameters_
- _state_ `Object`: State tree.
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _recordId_ `number`: Record ID.
- _recordId_ `number|string`: Record ID.

_Returns_

Expand Down
1 change: 1 addition & 0 deletions packages/core-data/src/batch/default-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export default async function defaultProcessor( requests ) {

const results = [];

// @ts-ignore We would have crashed or never gotten to this point if we hadn't received the maxItems count.
for ( const batchRequests of chunk( requests, maxItems ) ) {
const batchResponse = await apiFetch( {
path: '/batch/v1',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { __ } from '@wordpress/i18n';
/**
* Filters the search by type
*
* @typedef { 'post' | 'term' | 'post-format' } WPLinkSearchType
* @typedef { 'attachment' | 'post' | 'term' | 'post-format' } WPLinkSearchType
*/

/**
Expand Down Expand Up @@ -38,6 +38,17 @@ import { __ } from '@wordpress/i18n';
* @property {WPKind} [kind] Link kind of post-type or taxonomy
*/

/**
* @typedef WPLinkSearchResultAugments
*
* @property {{kind: WPKind}} [meta] Contains kind information.
* @property {WPKind} [subtype] Optional subtype if it exists.
*/

/**
* @typedef {WPLinkSearchResult & WPLinkSearchResultAugments} WPLinkSearchResultAugmented
*/

/**
* @typedef WPEditorSettings
*
Expand Down Expand Up @@ -82,6 +93,7 @@ const fetchLinkSuggestions = async (

const { disablePostFormats = false } = settings;

/** @type {Promise<WPLinkSearchResult>[]} */
const queries = [];

if ( ! type || type === 'post' ) {
Expand Down Expand Up @@ -177,7 +189,8 @@ const fetchLinkSuggestions = async (
return Promise.all( queries ).then( ( results ) => {
return results
.reduce(
( accumulator, current ) => accumulator.concat( current ), // Flatten list.
( /** @type {WPLinkSearchResult[]} */ accumulator, current ) =>
accumulator.concat( current ), // Flatten list.
[]
)
.filter(
Expand All @@ -189,27 +202,24 @@ const fetchLinkSuggestions = async (
}
)
.slice( 0, perPage )
.map(
/**
* @param {{ id: number, meta?: object, url:string, title?:string, subtype?: string, type?: string }} result
*/
( result ) => {
const isMedia = result.type === 'attachment';

return {
id: result.id,
url: isMedia ? result.source_url : result.url,
title:
decodeEntities(
isMedia
? result.title.rendered
: result.title || ''
) || __( '(no title)' ),
type: result.subtype || result.type,
kind: result?.meta?.kind,
};
}
);
.map( ( /** @type {WPLinkSearchResultAugmented} */ result ) => {
const isMedia = result.type === 'attachment';

return {
id: result.id,
// @ts-ignore fix when we make this a TS file
url: isMedia ? result.source_url : result.url,
title:
decodeEntities(
isMedia
? // @ts-ignore fix when we make this a TS file
result.title.rendered
: result.title || ''
) || __( '(no title)' ),
type: result.subtype || result.type,
kind: result?.meta?.kind,
};
} );
} );
};

Expand Down
15 changes: 12 additions & 3 deletions packages/core-data/src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { ifMatchingAction, replaceAction } from './utils';
import { reducer as queriedDataReducer } from './queried-data';
import { rootEntitiesConfig, DEFAULT_ENTITY_KEY } from './entities';

/** @typedef {import('./types').AnyFunction} AnyFunction */

/**
* Reducer managing terms state. Keyed by taxonomy slug, the value is either
* undefined (if no request has been made for given taxonomy), null (if a
Expand Down Expand Up @@ -185,7 +187,7 @@ export function themeGlobalStyleVariations( state = {}, action ) {
*
* @param {Object} entityConfig Entity config.
*
* @return {Function} Reducer.
* @return {AnyFunction} Reducer.
*/
function entity( entityConfig ) {
return flowRight( [
Expand Down Expand Up @@ -406,7 +408,11 @@ export const entities = ( state = {}, action ) => {

/** @typedef {Array<Object> & UndoStateMeta} UndoState */

/** @type {UndoState} */
/**
* @type {UndoState}
*
* @todo Given how we use this we might want to make a custom class for it.
*/
const UNDO_INITIAL_STATE = Object.assign( [], { offset: 0 } );

/** @type {Object} */
Expand All @@ -416,7 +422,7 @@ let lastEditAction;
* Reducer keeping track of entity edit undo history.
*
* @param {UndoState} state Current state.
* @param {Object} action Dispatched action.
* @param {Object} action Dispatched action.
*
* @return {UndoState} Updated state.
*/
Expand Down Expand Up @@ -455,6 +461,7 @@ export function undo( state = UNDO_INITIAL_STATE, action ) {
let nextState;

if ( isUndoOrRedo ) {
// @ts-ignore we might consider using Object.assign({}, state)
nextState = [ ...state ];
nextState.offset =
state.offset + ( action.meta.isUndo ? -1 : 1 );
Expand Down Expand Up @@ -494,6 +501,7 @@ export function undo( state = UNDO_INITIAL_STATE, action ) {
( key ) => ! action.transientEdits[ key ]
)
) {
// @ts-ignore we might consider using Object.assign({}, state)
nextState = [ ...state ];
nextState.flattenedUndo = {
...state.flattenedUndo,
Expand All @@ -505,6 +513,7 @@ export function undo( state = UNDO_INITIAL_STATE, action ) {

// Clear potential redos, because this only supports linear history.
nextState =
// @ts-ignore this needs additional cleanup, probably involving code-level changes
nextState || state.slice( 0, state.offset || undefined );
nextState.offset = nextState.offset || 0;
nextState.pop();
Expand Down
8 changes: 4 additions & 4 deletions packages/core-data/src/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -501,10 +501,10 @@ export const getEntityRecordNonTransientEdits = createSelector(
* Returns true if the specified entity record has edits,
* and false otherwise.
*
* @param {Object} state State tree.
* @param {string} kind Entity kind.
* @param {string} name Entity name.
* @param {number} recordId Record ID.
* @param {Object} state State tree.
* @param {string} kind Entity kind.
* @param {string} name Entity name.
* @param {number|string} recordId Record ID.
*
* @return {boolean} Whether the entity record has edits or not.
*/
Expand Down
6 changes: 4 additions & 2 deletions packages/core-data/src/utils/if-matching-action.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/** @typedef {import('../types').AnyFunction} AnyFunction */

/**
* A higher-order reducer creator which invokes the original reducer only if
* the dispatching action matches the given predicate, **OR** if state is
* initializing (undefined).
*
* @param {Function} isMatch Function predicate for allowing reducer call.
* @param {AnyFunction} isMatch Function predicate for allowing reducer call.
*
* @return {Function} Higher-order reducer.
* @return {AnyFunction} Higher-order reducer.
*/
const ifMatchingAction = ( isMatch ) => ( reducer ) => ( state, action ) => {
if ( state === undefined || isMatch( action ) ) {
Expand Down
6 changes: 4 additions & 2 deletions packages/core-data/src/utils/replace-action.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/** @typedef {import('../types').AnyFunction} AnyFunction */

/**
* Higher-order reducer creator which substitutes the action object before
* passing to the original reducer.
*
* @param {Function} replacer Function mapping original action to replacement.
* @param {AnyFunction} replacer Function mapping original action to replacement.
*
* @return {Function} Higher-order reducer.
* @return {AnyFunction} Higher-order reducer.
*/
const replaceAction = ( replacer ) => ( reducer ) => ( state, action ) => {
return reducer( state, replacer( action ) );
Expand Down