@wordpress/core-data 7.9.0 → 7.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/build/actions.js +13 -9
  3. package/build/actions.js.map +1 -1
  4. package/build/batch/create-batch.js +1 -0
  5. package/build/batch/create-batch.js.map +1 -1
  6. package/build/entities.js +1 -63
  7. package/build/entities.js.map +1 -1
  8. package/build/entity-types/attachment.js.map +1 -1
  9. package/build/fetch/__experimental-fetch-url-data.js.map +1 -1
  10. package/build/hooks/use-entity-block-editor.js +4 -5
  11. package/build/hooks/use-entity-block-editor.js.map +1 -1
  12. package/build/hooks/use-entity-record.js.map +1 -1
  13. package/build/hooks/use-entity-records.js.map +1 -1
  14. package/build/hooks/use-resource-permissions.js.map +1 -1
  15. package/build/resolvers.js +56 -24
  16. package/build/resolvers.js.map +1 -1
  17. package/build/selectors.js.map +1 -1
  18. package/build-module/actions.js +14 -10
  19. package/build-module/actions.js.map +1 -1
  20. package/build-module/batch/create-batch.js +1 -0
  21. package/build-module/batch/create-batch.js.map +1 -1
  22. package/build-module/entities.js +0 -61
  23. package/build-module/entities.js.map +1 -1
  24. package/build-module/entity-types/attachment.js.map +1 -1
  25. package/build-module/fetch/__experimental-fetch-url-data.js.map +1 -1
  26. package/build-module/hooks/use-entity-block-editor.js +4 -5
  27. package/build-module/hooks/use-entity-block-editor.js.map +1 -1
  28. package/build-module/hooks/use-entity-record.js.map +1 -1
  29. package/build-module/hooks/use-entity-records.js.map +1 -1
  30. package/build-module/hooks/use-resource-permissions.js.map +1 -1
  31. package/build-module/resolvers.js +55 -24
  32. package/build-module/resolvers.js.map +1 -1
  33. package/build-module/selectors.js.map +1 -1
  34. package/build-types/actions.d.ts +8 -4
  35. package/build-types/actions.d.ts.map +1 -1
  36. package/build-types/entities.d.ts +0 -1
  37. package/build-types/entities.d.ts.map +1 -1
  38. package/build-types/entity-types/attachment.d.ts +36 -1
  39. package/build-types/entity-types/attachment.d.ts.map +1 -1
  40. package/build-types/hooks/use-entity-block-editor.d.ts.map +1 -1
  41. package/build-types/index.d.ts +8 -4
  42. package/build-types/index.d.ts.map +1 -1
  43. package/build-types/resolvers.d.ts +13 -5
  44. package/build-types/resolvers.d.ts.map +1 -1
  45. package/package.json +20 -19
  46. package/src/actions.js +10 -10
  47. package/src/entities.js +0 -64
  48. package/src/entity-types/attachment.ts +35 -1
  49. package/src/hooks/test/use-entity-record.js +9 -2
  50. package/src/hooks/use-entity-block-editor.js +4 -9
  51. package/src/resolvers.js +59 -29
  52. package/src/test/actions.js +24 -39
  53. package/src/test/entities.js +0 -80
  54. package/src/test/resolvers.js +89 -35
  55. package/tsconfig.tsbuildinfo +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/core-data",
3
- "version": "7.9.0",
3
+ "version": "7.11.0",
4
4
  "description": "Access to and manipulation of core WordPress entities.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -31,23 +31,23 @@
31
31
  "{src,build,build-module}/index.js"
32
32
  ],
33
33
  "dependencies": {
34
- "@babel/runtime": "^7.16.0",
35
- "@wordpress/api-fetch": "^7.9.0",
36
- "@wordpress/block-editor": "^14.4.0",
37
- "@wordpress/blocks": "^13.9.0",
38
- "@wordpress/compose": "^7.9.0",
39
- "@wordpress/data": "^10.9.0",
40
- "@wordpress/deprecated": "^4.9.0",
41
- "@wordpress/element": "^6.9.0",
42
- "@wordpress/html-entities": "^4.9.0",
43
- "@wordpress/i18n": "^5.9.0",
44
- "@wordpress/is-shallow-equal": "^5.9.0",
45
- "@wordpress/private-apis": "^1.9.0",
46
- "@wordpress/rich-text": "^7.9.0",
47
- "@wordpress/sync": "^1.9.0",
48
- "@wordpress/undo-manager": "^1.9.0",
49
- "@wordpress/url": "^4.9.0",
50
- "@wordpress/warning": "^3.9.0",
34
+ "@babel/runtime": "7.25.7",
35
+ "@wordpress/api-fetch": "*",
36
+ "@wordpress/block-editor": "*",
37
+ "@wordpress/blocks": "*",
38
+ "@wordpress/compose": "*",
39
+ "@wordpress/data": "*",
40
+ "@wordpress/deprecated": "*",
41
+ "@wordpress/element": "*",
42
+ "@wordpress/html-entities": "*",
43
+ "@wordpress/i18n": "*",
44
+ "@wordpress/is-shallow-equal": "*",
45
+ "@wordpress/private-apis": "*",
46
+ "@wordpress/rich-text": "*",
47
+ "@wordpress/sync": "*",
48
+ "@wordpress/undo-manager": "*",
49
+ "@wordpress/url": "*",
50
+ "@wordpress/warning": "*",
51
51
  "change-case": "^4.1.2",
52
52
  "equivalent-key-map": "^0.2.2",
53
53
  "fast-deep-equal": "^3.1.3",
@@ -61,5 +61,6 @@
61
61
  "publishConfig": {
62
62
  "access": "public"
63
63
  },
64
- "gitHead": "2e5495c635910cb34bfaca3c6258d2e989f66214"
64
+ "wpScript": true,
65
+ "gitHead": "dcf4613b33b0eda14e203ac30f700ed0db70347f"
65
66
  }
package/src/actions.js CHANGED
@@ -16,7 +16,7 @@ import deprecated from '@wordpress/deprecated';
16
16
  */
17
17
  import { getNestedValue, setNestedValue } from './utils';
18
18
  import { receiveItems, removeItems, receiveQueriedItems } from './queried-data';
19
- import { getOrLoadEntitiesConfig, DEFAULT_ENTITY_KEY } from './entities';
19
+ import { DEFAULT_ENTITY_KEY } from './entities';
20
20
  import { createBatch } from './batch';
21
21
  import { STORE_NAME } from './name';
22
22
  import { getSyncProvider } from './sync';
@@ -285,8 +285,8 @@ export const deleteEntityRecord =
285
285
  query,
286
286
  { __unstableFetch = apiFetch, throwOnError = false } = {}
287
287
  ) =>
288
- async ( { dispatch } ) => {
289
- const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
288
+ async ( { dispatch, resolveSelect } ) => {
289
+ const configs = await resolveSelect.getEntitiesConfig( kind );
290
290
  const entityConfig = configs.find(
291
291
  ( config ) => config.kind === kind && config.name === name
292
292
  );
@@ -503,7 +503,7 @@ export const saveEntityRecord =
503
503
  } = {}
504
504
  ) =>
505
505
  async ( { select, resolveSelect, dispatch } ) => {
506
- const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
506
+ const configs = await resolveSelect.getEntitiesConfig( kind );
507
507
  const entityConfig = configs.find(
508
508
  ( config ) => config.kind === kind && config.name === name
509
509
  );
@@ -780,11 +780,11 @@ export const __experimentalBatch =
780
780
  */
781
781
  export const saveEditedEntityRecord =
782
782
  ( kind, name, recordId, options ) =>
783
- async ( { select, dispatch } ) => {
783
+ async ( { select, dispatch, resolveSelect } ) => {
784
784
  if ( ! select.hasEditsForEntityRecord( kind, name, recordId ) ) {
785
785
  return;
786
786
  }
787
- const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
787
+ const configs = await resolveSelect.getEntitiesConfig( kind );
788
788
  const entityConfig = configs.find(
789
789
  ( config ) => config.kind === kind && config.name === name
790
790
  );
@@ -813,7 +813,7 @@ export const saveEditedEntityRecord =
813
813
  */
814
814
  export const __experimentalSaveSpecifiedEntityEdits =
815
815
  ( kind, name, recordId, itemsToSave, options ) =>
816
- async ( { select, dispatch } ) => {
816
+ async ( { select, dispatch, resolveSelect } ) => {
817
817
  if ( ! select.hasEditsForEntityRecord( kind, name, recordId ) ) {
818
818
  return;
819
819
  }
@@ -828,7 +828,7 @@ export const __experimentalSaveSpecifiedEntityEdits =
828
828
  setNestedValue( editsToSave, item, getNestedValue( edits, item ) );
829
829
  }
830
830
 
831
- const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
831
+ const configs = await resolveSelect.getEntitiesConfig( kind );
832
832
  const entityConfig = configs.find(
833
833
  ( config ) => config.kind === kind && config.name === name
834
834
  );
@@ -973,8 +973,8 @@ export function receiveDefaultTemplateId( query, templateId ) {
973
973
  */
974
974
  export const receiveRevisions =
975
975
  ( kind, name, recordKey, records, query, invalidateCache = false, meta ) =>
976
- async ( { dispatch } ) => {
977
- const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
976
+ async ( { dispatch, resolveSelect } ) => {
977
+ const configs = await resolveSelect.getEntitiesConfig( kind );
978
978
  const entityConfig = configs.find(
979
979
  ( config ) => config.kind === kind && config.name === name
980
980
  );
package/src/entities.js CHANGED
@@ -10,14 +10,7 @@ import apiFetch from '@wordpress/api-fetch';
10
10
  import { __ } from '@wordpress/i18n';
11
11
  import { RichTextData } from '@wordpress/rich-text';
12
12
 
13
- /**
14
- * Internal dependencies
15
- */
16
- import { addEntities } from './actions';
17
- import { getSyncProvider } from './sync';
18
-
19
13
  export const DEFAULT_ENTITY_KEY = 'id';
20
-
21
14
  const POST_RAW_ATTRIBUTES = [ 'title', 'excerpt', 'content' ];
22
15
 
23
16
  export const rootEntitiesConfig = [
@@ -458,60 +451,3 @@ export const getMethodName = ( kind, name, prefix = 'get' ) => {
458
451
  const suffix = pascalCase( name );
459
452
  return `${ prefix }${ kindPrefix }${ suffix }`;
460
453
  };
461
-
462
- function registerSyncConfigs( configs ) {
463
- configs.forEach( ( { syncObjectType, syncConfig } ) => {
464
- getSyncProvider().register( syncObjectType, syncConfig );
465
- const editSyncConfig = { ...syncConfig };
466
- delete editSyncConfig.fetch;
467
- getSyncProvider().register( syncObjectType + '--edit', editSyncConfig );
468
- } );
469
- }
470
-
471
- /**
472
- * Loads the entities into the store.
473
- *
474
- * Note: The `name` argument is used for `root` entities requiring additional server data.
475
- *
476
- * @param {string} kind Kind
477
- * @param {string} name Name
478
- * @return {(thunkArgs: object) => Promise<Array>} Entities
479
- */
480
- export const getOrLoadEntitiesConfig =
481
- ( kind, name ) =>
482
- async ( { select, dispatch } ) => {
483
- let configs = select.getEntitiesConfig( kind );
484
- const hasConfig = !! select.getEntityConfig( kind, name );
485
-
486
- if ( configs?.length > 0 && hasConfig ) {
487
- if ( window.__experimentalEnableSync ) {
488
- if ( globalThis.IS_GUTENBERG_PLUGIN ) {
489
- registerSyncConfigs( configs );
490
- }
491
- }
492
-
493
- return configs;
494
- }
495
-
496
- const loader = additionalEntityConfigLoaders.find( ( l ) => {
497
- if ( ! name || ! l.name ) {
498
- return l.kind === kind;
499
- }
500
-
501
- return l.kind === kind && l.name === name;
502
- } );
503
- if ( ! loader ) {
504
- return [];
505
- }
506
-
507
- configs = await loader.loadEntities();
508
- if ( window.__experimentalEnableSync ) {
509
- if ( globalThis.IS_GUTENBERG_PLUGIN ) {
510
- registerSyncConfigs( configs );
511
- }
512
- }
513
-
514
- dispatch( addEntities( configs ) );
515
-
516
- return configs;
517
- };
@@ -14,6 +14,40 @@ import type {
14
14
 
15
15
  import type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records';
16
16
 
17
+ interface MediaDetails {
18
+ width: number;
19
+ height: number;
20
+ file: string;
21
+ filesize: number;
22
+ sizes: { [ key: string ]: Size };
23
+ image_meta: ImageMeta;
24
+ original_image?: string;
25
+ }
26
+ interface ImageMeta {
27
+ aperture: string;
28
+ credit: string;
29
+ camera: string;
30
+ caption: string;
31
+ created_timestamp: string;
32
+ copyright: string;
33
+ focal_length: string;
34
+ iso: string;
35
+ shutter_speed: string;
36
+ title: string;
37
+ orientation: string;
38
+ keywords: any[];
39
+ }
40
+
41
+ interface Size {
42
+ file: string;
43
+ width: number;
44
+ height: number;
45
+ filesize?: number;
46
+ mime_type: string;
47
+ source_url: string;
48
+ uncropped?: boolean;
49
+ }
50
+
17
51
  declare module './base-entity-records' {
18
52
  export namespace BaseEntityRecords {
19
53
  export interface Attachment< C extends Context > {
@@ -124,7 +158,7 @@ declare module './base-entity-records' {
124
158
  /**
125
159
  * Details about the media file, specific to its type.
126
160
  */
127
- media_details: Record< string, string >;
161
+ media_details: MediaDetails;
128
162
  /**
129
163
  * The ID for the associated post of the attachment.
130
164
  */
@@ -140,7 +140,14 @@ describe( 'useEntityRecord', () => {
140
140
  await act(
141
141
  () => new Promise( ( resolve ) => setTimeout( resolve, 0 ) )
142
142
  );
143
- expect( triggerFetch ).toHaveBeenCalledTimes( 1 );
143
+ await waitFor( () =>
144
+ expect( triggerFetch ).toHaveBeenCalledWith( {
145
+ path: '/wp/v2/widgets/1?context=edit',
146
+ parse: false,
147
+ } )
148
+ );
149
+ // Clear the fetch call history.
150
+ triggerFetch.mockReset();
144
151
 
145
152
  rerender( <UI enabled={ false } /> );
146
153
 
@@ -157,6 +164,6 @@ describe( 'useEntityRecord', () => {
157
164
  await act(
158
165
  () => new Promise( ( resolve ) => setTimeout( resolve, 0 ) )
159
166
  );
160
- expect( triggerFetch ).toHaveBeenCalledTimes( 1 );
167
+ expect( triggerFetch ).toHaveBeenCalledTimes( 0 );
161
168
  } );
162
169
  } );
@@ -91,11 +91,6 @@ export default function useEntityBlockEditor( kind, name, { id: _id } = {} ) {
91
91
  getEntityRecordEdits,
92
92
  ] );
93
93
 
94
- const updateFootnotes = useCallback(
95
- ( _blocks ) => updateFootnotesFromMeta( _blocks, meta ),
96
- [ meta ]
97
- );
98
-
99
94
  const onChange = useCallback(
100
95
  ( newBlocks, options ) => {
101
96
  const noChange = blocks === newBlocks;
@@ -111,7 +106,7 @@ export default function useEntityBlockEditor( kind, name, { id: _id } = {} ) {
111
106
  selection,
112
107
  content: ( { blocks: blocksForSerialization = [] } ) =>
113
108
  __unstableSerializeAndClean( blocksForSerialization ),
114
- ...updateFootnotes( newBlocks ),
109
+ ...updateFootnotesFromMeta( newBlocks, meta ),
115
110
  };
116
111
 
117
112
  editEntityRecord( kind, name, id, edits, {
@@ -124,7 +119,7 @@ export default function useEntityBlockEditor( kind, name, { id: _id } = {} ) {
124
119
  name,
125
120
  id,
126
121
  blocks,
127
- updateFootnotes,
122
+ meta,
128
123
  __unstableCreateUndoLevel,
129
124
  editEntityRecord,
130
125
  ]
@@ -133,7 +128,7 @@ export default function useEntityBlockEditor( kind, name, { id: _id } = {} ) {
133
128
  const onInput = useCallback(
134
129
  ( newBlocks, options ) => {
135
130
  const { selection, ...rest } = options;
136
- const footnotesChanges = updateFootnotes( newBlocks );
131
+ const footnotesChanges = updateFootnotesFromMeta( newBlocks, meta );
137
132
  const edits = { selection, ...footnotesChanges };
138
133
 
139
134
  editEntityRecord( kind, name, id, edits, {
@@ -141,7 +136,7 @@ export default function useEntityBlockEditor( kind, name, { id: _id } = {} ) {
141
136
  ...rest,
142
137
  } );
143
138
  },
144
- [ kind, name, id, updateFootnotes, editEntityRecord ]
139
+ [ kind, name, id, meta, editEntityRecord ]
145
140
  );
146
141
 
147
142
  return [ blocks, onInput, onChange ];
package/src/resolvers.js CHANGED
@@ -14,7 +14,7 @@ import apiFetch from '@wordpress/api-fetch';
14
14
  * Internal dependencies
15
15
  */
16
16
  import { STORE_NAME } from './name';
17
- import { getOrLoadEntitiesConfig, DEFAULT_ENTITY_KEY } from './entities';
17
+ import { additionalEntityConfigLoaders, DEFAULT_ENTITY_KEY } from './entities';
18
18
  import {
19
19
  forwardResolver,
20
20
  getNormalizedCommaSeparable,
@@ -64,8 +64,8 @@ export const getCurrentUser =
64
64
  */
65
65
  export const getEntityRecord =
66
66
  ( kind, name, key = '', query ) =>
67
- async ( { select, dispatch, registry } ) => {
68
- const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
67
+ async ( { select, dispatch, registry, resolveSelect } ) => {
68
+ const configs = await resolveSelect.getEntitiesConfig( kind );
69
69
  const entityConfig = configs.find(
70
70
  ( config ) => config.name === name && config.kind === kind
71
71
  );
@@ -230,8 +230,8 @@ export const getEditedEntityRecord = forwardResolver( 'getEntityRecord' );
230
230
  */
231
231
  export const getEntityRecords =
232
232
  ( kind, name, query = {} ) =>
233
- async ( { dispatch, registry } ) => {
234
- const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
233
+ async ( { dispatch, registry, resolveSelect } ) => {
234
+ const configs = await resolveSelect.getEntitiesConfig( kind );
235
235
  const entityConfig = configs.find(
236
236
  ( config ) => config.name === name && config.kind === kind
237
237
  );
@@ -431,19 +431,36 @@ export const getEmbedPreview =
431
431
  */
432
432
  export const canUser =
433
433
  ( requestedAction, resource, id ) =>
434
- async ( { dispatch, registry } ) => {
434
+ async ( { dispatch, registry, resolveSelect } ) => {
435
435
  if ( ! ALLOWED_RESOURCE_ACTIONS.includes( requestedAction ) ) {
436
436
  throw new Error( `'${ requestedAction }' is not a valid action.` );
437
437
  }
438
438
 
439
+ const { hasStartedResolution } = registry.select( STORE_NAME );
440
+
441
+ // Prevent resolving the same resource twice.
442
+ for ( const relatedAction of ALLOWED_RESOURCE_ACTIONS ) {
443
+ if ( relatedAction === requestedAction ) {
444
+ continue;
445
+ }
446
+ const isAlreadyResolving = hasStartedResolution( 'canUser', [
447
+ relatedAction,
448
+ resource,
449
+ id,
450
+ ] );
451
+ if ( isAlreadyResolving ) {
452
+ return;
453
+ }
454
+ }
455
+
439
456
  let resourcePath = null;
440
457
  if ( typeof resource === 'object' ) {
441
458
  if ( ! resource.kind || ! resource.name ) {
442
459
  throw new Error( 'The entity resource object is not valid.' );
443
460
  }
444
461
 
445
- const configs = await dispatch(
446
- getOrLoadEntitiesConfig( resource.kind, resource.name )
462
+ const configs = await resolveSelect.getEntitiesConfig(
463
+ resource.kind
447
464
  );
448
465
  const entityConfig = configs.find(
449
466
  ( config ) =>
@@ -460,23 +477,6 @@ export const canUser =
460
477
  resourcePath = `/wp/v2/${ resource }` + ( id ? '/' + id : '' );
461
478
  }
462
479
 
463
- const { hasStartedResolution } = registry.select( STORE_NAME );
464
-
465
- // Prevent resolving the same resource twice.
466
- for ( const relatedAction of ALLOWED_RESOURCE_ACTIONS ) {
467
- if ( relatedAction === requestedAction ) {
468
- continue;
469
- }
470
- const isAlreadyResolving = hasStartedResolution( 'canUser', [
471
- relatedAction,
472
- resource,
473
- id,
474
- ] );
475
- if ( isAlreadyResolving ) {
476
- return;
477
- }
478
- }
479
-
480
480
  let response;
481
481
  try {
482
482
  response = await apiFetch( {
@@ -644,6 +644,7 @@ export const __experimentalGetCurrentThemeBaseGlobalStyles =
644
644
  () =>
645
645
  async ( { resolveSelect, dispatch } ) => {
646
646
  const currentTheme = await resolveSelect.getCurrentTheme();
647
+ // Please adjust the preloaded requests if this changes!
647
648
  const themeGlobalStyles = await apiFetch( {
648
649
  path: `/wp/v2/global-styles/themes/${ currentTheme.stylesheet }?context=view`,
649
650
  } );
@@ -657,6 +658,7 @@ export const __experimentalGetCurrentThemeGlobalStylesVariations =
657
658
  () =>
658
659
  async ( { resolveSelect, dispatch } ) => {
659
660
  const currentTheme = await resolveSelect.getCurrentTheme();
661
+ // Please adjust the preloaded requests if this changes!
660
662
  const variations = await apiFetch( {
661
663
  path: `/wp/v2/global-styles/themes/${ currentTheme.stylesheet }/variations?context=view`,
662
664
  } );
@@ -821,8 +823,8 @@ export const getDefaultTemplateId =
821
823
  */
822
824
  export const getRevisions =
823
825
  ( kind, name, recordKey, query = {} ) =>
824
- async ( { dispatch, registry } ) => {
825
- const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
826
+ async ( { dispatch, registry, resolveSelect } ) => {
827
+ const configs = await resolveSelect.getEntitiesConfig( kind );
826
828
  const entityConfig = configs.find(
827
829
  ( config ) => config.name === name && config.kind === kind
828
830
  );
@@ -942,8 +944,8 @@ getRevisions.shouldInvalidate = ( action, kind, name, recordKey ) =>
942
944
  */
943
945
  export const getRevision =
944
946
  ( kind, name, recordKey, revisionKey, query ) =>
945
- async ( { dispatch } ) => {
946
- const configs = await dispatch( getOrLoadEntitiesConfig( kind, name ) );
947
+ async ( { dispatch, resolveSelect } ) => {
948
+ const configs = await resolveSelect.getEntitiesConfig( kind );
947
949
  const entityConfig = configs.find(
948
950
  ( config ) => config.name === name && config.kind === kind
949
951
  );
@@ -1015,3 +1017,31 @@ export const getRegisteredPostMeta =
1015
1017
  );
1016
1018
  }
1017
1019
  };
1020
+
1021
+ /**
1022
+ * Requests entity configs for the given kind from the REST API.
1023
+ *
1024
+ * @param {string} kind Entity kind.
1025
+ */
1026
+ export const getEntitiesConfig =
1027
+ ( kind ) =>
1028
+ async ( { dispatch } ) => {
1029
+ const loader = additionalEntityConfigLoaders.find(
1030
+ ( l ) => l.kind === kind
1031
+ );
1032
+
1033
+ if ( ! loader ) {
1034
+ return;
1035
+ }
1036
+
1037
+ try {
1038
+ const configs = await loader.loadEntities();
1039
+ if ( ! configs.length ) {
1040
+ return;
1041
+ }
1042
+
1043
+ dispatch.addEntities( configs );
1044
+ } catch {
1045
+ // Do nothing if the request comes back with an API error.
1046
+ }
1047
+ };