@wordpress/core-data 4.0.1 → 4.0.5

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 (116) hide show
  1. package/README.md +13 -7
  2. package/build/actions.js +178 -122
  3. package/build/actions.js.map +1 -1
  4. package/build/batch/default-processor.js +58 -27
  5. package/build/batch/default-processor.js.map +1 -1
  6. package/build/entities.js +70 -23
  7. package/build/entities.js.map +1 -1
  8. package/build/fetch/__experimental-fetch-url-data.js +1 -1
  9. package/build/fetch/__experimental-fetch-url-data.js.map +1 -1
  10. package/build/index.js +9 -17
  11. package/build/index.js.map +1 -1
  12. package/build/locks/actions.js +17 -77
  13. package/build/locks/actions.js.map +1 -1
  14. package/build/locks/engine.js +77 -0
  15. package/build/locks/engine.js.map +1 -0
  16. package/build/locks/reducer.js +1 -5
  17. package/build/locks/reducer.js.map +1 -1
  18. package/build/locks/selectors.js +6 -6
  19. package/build/locks/selectors.js.map +1 -1
  20. package/build/queried-data/get-query-parts.js +9 -4
  21. package/build/queried-data/get-query-parts.js.map +1 -1
  22. package/build/queried-data/selectors.js +3 -9
  23. package/build/queried-data/selectors.js.map +1 -1
  24. package/build/reducer.js +17 -22
  25. package/build/reducer.js.map +1 -1
  26. package/build/resolvers.js +151 -97
  27. package/build/resolvers.js.map +1 -1
  28. package/build/selectors.js +79 -14
  29. package/build/selectors.js.map +1 -1
  30. package/build/utils/forward-resolver.js +23 -0
  31. package/build/utils/forward-resolver.js.map +1 -0
  32. package/build/utils/index.js +11 -3
  33. package/build/utils/index.js.map +1 -1
  34. package/build/utils/is-raw-attribute.js +19 -0
  35. package/build/utils/is-raw-attribute.js.map +1 -0
  36. package/build-module/actions.js +155 -112
  37. package/build-module/actions.js.map +1 -1
  38. package/build-module/batch/default-processor.js +57 -27
  39. package/build-module/batch/default-processor.js.map +1 -1
  40. package/build-module/entities.js +65 -19
  41. package/build-module/entities.js.map +1 -1
  42. package/build-module/fetch/__experimental-fetch-url-data.js +1 -1
  43. package/build-module/fetch/__experimental-fetch-url-data.js.map +1 -1
  44. package/build-module/index.js +10 -14
  45. package/build-module/index.js.map +1 -1
  46. package/build-module/locks/actions.js +14 -68
  47. package/build-module/locks/actions.js.map +1 -1
  48. package/build-module/locks/engine.js +66 -0
  49. package/build-module/locks/engine.js.map +1 -0
  50. package/build-module/locks/reducer.js +1 -2
  51. package/build-module/locks/reducer.js.map +1 -1
  52. package/build-module/locks/selectors.js +4 -4
  53. package/build-module/locks/selectors.js.map +1 -1
  54. package/build-module/queried-data/get-query-parts.js +9 -4
  55. package/build-module/queried-data/get-query-parts.js.map +1 -1
  56. package/build-module/queried-data/selectors.js +3 -9
  57. package/build-module/queried-data/selectors.js.map +1 -1
  58. package/build-module/reducer.js +15 -19
  59. package/build-module/reducer.js.map +1 -1
  60. package/build-module/resolvers.js +123 -81
  61. package/build-module/resolvers.js.map +1 -1
  62. package/build-module/selectors.js +74 -13
  63. package/build-module/selectors.js.map +1 -1
  64. package/build-module/utils/forward-resolver.js +15 -0
  65. package/build-module/utils/forward-resolver.js.map +1 -0
  66. package/build-module/utils/index.js +2 -1
  67. package/build-module/utils/index.js.map +1 -1
  68. package/build-module/utils/is-raw-attribute.js +12 -0
  69. package/build-module/utils/is-raw-attribute.js.map +1 -0
  70. package/package.json +10 -11
  71. package/src/actions.js +163 -194
  72. package/src/batch/default-processor.js +57 -26
  73. package/src/batch/test/default-processor.js +53 -26
  74. package/src/entities.js +47 -19
  75. package/src/fetch/__experimental-fetch-url-data.js +1 -1
  76. package/src/index.js +7 -10
  77. package/src/locks/actions.js +10 -61
  78. package/src/locks/engine.js +43 -0
  79. package/src/locks/reducer.js +1 -3
  80. package/src/locks/selectors.js +4 -4
  81. package/src/locks/test/engine.js +135 -0
  82. package/src/locks/test/reducer.js +1 -1
  83. package/src/locks/test/selectors.js +105 -124
  84. package/src/queried-data/get-query-parts.js +11 -6
  85. package/src/queried-data/selectors.js +2 -9
  86. package/src/queried-data/test/get-query-parts.js +1 -1
  87. package/src/queried-data/test/selectors.js +1 -0
  88. package/src/reducer.js +14 -19
  89. package/src/resolvers.js +132 -120
  90. package/src/selectors.js +156 -44
  91. package/src/test/actions.js +330 -170
  92. package/src/test/entities.js +40 -26
  93. package/src/test/resolvers.js +270 -223
  94. package/src/test/selectors.js +127 -1
  95. package/src/utils/forward-resolver.js +14 -0
  96. package/src/utils/index.js +2 -1
  97. package/src/utils/is-raw-attribute.js +11 -0
  98. package/src/utils/test/is-raw-attribute.js +22 -0
  99. package/build/controls.js +0 -44
  100. package/build/controls.js.map +0 -1
  101. package/build/locks/index.js +0 -47
  102. package/build/locks/index.js.map +0 -1
  103. package/build/utils/if-not-resolved.js +0 -46
  104. package/build/utils/if-not-resolved.js.map +0 -1
  105. package/build-module/controls.js +0 -31
  106. package/build-module/controls.js.map +0 -1
  107. package/build-module/locks/index.js +0 -4
  108. package/build-module/locks/index.js.map +0 -1
  109. package/build-module/utils/if-not-resolved.js +0 -36
  110. package/build-module/utils/if-not-resolved.js.map +0 -1
  111. package/src/controls.js +0 -31
  112. package/src/locks/index.js +0 -3
  113. package/src/locks/test/actions.js +0 -307
  114. package/src/test/integration.js +0 -264
  115. package/src/utils/if-not-resolved.js +0 -40
  116. package/src/utils/test/if-not-resolved.js +0 -75
package/src/selectors.js CHANGED
@@ -17,7 +17,16 @@ import deprecated from '@wordpress/deprecated';
17
17
  import { STORE_NAME } from './name';
18
18
  import { getQueriedItems } from './queried-data';
19
19
  import { DEFAULT_ENTITY_KEY } from './entities';
20
- import { getNormalizedCommaSeparable } from './utils';
20
+ import { getNormalizedCommaSeparable, isRawAttribute } from './utils';
21
+
22
+ /**
23
+ * Shared reference to an empty object for cases where it is important to avoid
24
+ * returning a new object reference on every invocation, as in a connected or
25
+ * other pure component which performs `shouldComponentUpdate` check on props.
26
+ * This should be used as a last resort, since the normalized data should be
27
+ * maintained by the reducer result in state.
28
+ */
29
+ const EMPTY_OBJECT = {};
21
30
 
22
31
  /**
23
32
  * Shared reference to an empty array for cases where it is important to avoid
@@ -134,40 +143,63 @@ export function getEntity( state, kind, name ) {
134
143
  *
135
144
  * @return {Object?} Record.
136
145
  */
137
- export function getEntityRecord( state, kind, name, key, query ) {
138
- const queriedState = get( state.entities.data, [
139
- kind,
140
- name,
141
- 'queriedData',
142
- ] );
143
- if ( ! queriedState ) {
144
- return undefined;
145
- }
146
- const context = query?.context ?? 'default';
147
-
148
- if ( query === undefined ) {
149
- // If expecting a complete item, validate that completeness.
150
- if ( ! queriedState.itemIsComplete[ context ]?.[ key ] ) {
146
+ export const getEntityRecord = createSelector(
147
+ ( state, kind, name, key, query ) => {
148
+ const queriedState = get( state.entities.data, [
149
+ kind,
150
+ name,
151
+ 'queriedData',
152
+ ] );
153
+ if ( ! queriedState ) {
151
154
  return undefined;
152
155
  }
156
+ const context = query?.context ?? 'default';
153
157
 
154
- return queriedState.items[ context ][ key ];
155
- }
158
+ if ( query === undefined ) {
159
+ // If expecting a complete item, validate that completeness.
160
+ if ( ! queriedState.itemIsComplete[ context ]?.[ key ] ) {
161
+ return undefined;
162
+ }
156
163
 
157
- const item = queriedState.items[ context ]?.[ key ];
158
- if ( item && query._fields ) {
159
- const filteredItem = {};
160
- const fields = getNormalizedCommaSeparable( query._fields );
161
- for ( let f = 0; f < fields.length; f++ ) {
162
- const field = fields[ f ].split( '.' );
163
- const value = get( item, field );
164
- set( filteredItem, field, value );
164
+ return queriedState.items[ context ][ key ];
165
165
  }
166
- return filteredItem;
167
- }
168
166
 
169
- return item;
170
- }
167
+ const item = queriedState.items[ context ]?.[ key ];
168
+ if ( item && query._fields ) {
169
+ const filteredItem = {};
170
+ const fields = getNormalizedCommaSeparable( query._fields );
171
+ for ( let f = 0; f < fields.length; f++ ) {
172
+ const field = fields[ f ].split( '.' );
173
+ const value = get( item, field );
174
+ set( filteredItem, field, value );
175
+ }
176
+ return filteredItem;
177
+ }
178
+
179
+ return item;
180
+ },
181
+ ( state, kind, name, recordId, query ) => {
182
+ const context = query?.context ?? 'default';
183
+ return [
184
+ get( state.entities.data, [
185
+ kind,
186
+ name,
187
+ 'queriedData',
188
+ 'items',
189
+ context,
190
+ recordId,
191
+ ] ),
192
+ get( state.entities.data, [
193
+ kind,
194
+ name,
195
+ 'queriedData',
196
+ 'itemIsComplete',
197
+ context,
198
+ recordId,
199
+ ] ),
200
+ ];
201
+ }
202
+ );
171
203
 
172
204
  /**
173
205
  * Returns the Entity's record object by key. Doesn't trigger a resolver nor requests the entity from the API if the entity record isn't available in the local state.
@@ -205,19 +237,44 @@ export const getRawEntityRecord = createSelector(
205
237
  return (
206
238
  record &&
207
239
  Object.keys( record ).reduce( ( accumulator, _key ) => {
208
- // Because edits are the "raw" attribute values,
209
- // we return those from record selectors to make rendering,
210
- // comparisons, and joins with edits easier.
211
- accumulator[ _key ] = get(
212
- record[ _key ],
213
- 'raw',
214
- record[ _key ]
215
- );
240
+ if ( isRawAttribute( getEntity( state, kind, name ), _key ) ) {
241
+ // Because edits are the "raw" attribute values,
242
+ // we return those from record selectors to make rendering,
243
+ // comparisons, and joins with edits easier.
244
+ accumulator[ _key ] = get(
245
+ record[ _key ],
246
+ 'raw',
247
+ record[ _key ]
248
+ );
249
+ } else {
250
+ accumulator[ _key ] = record[ _key ];
251
+ }
216
252
  return accumulator;
217
253
  }, {} )
218
254
  );
219
255
  },
220
- ( state ) => [ state.entities.data ]
256
+ ( state, kind, name, recordId, query ) => {
257
+ const context = query?.context ?? 'default';
258
+ return [
259
+ state.entities.config,
260
+ get( state.entities.data, [
261
+ kind,
262
+ name,
263
+ 'queriedData',
264
+ 'items',
265
+ context,
266
+ recordId,
267
+ ] ),
268
+ get( state.entities.data, [
269
+ kind,
270
+ name,
271
+ 'queriedData',
272
+ 'itemIsComplete',
273
+ context,
274
+ recordId,
275
+ ] ),
276
+ ];
277
+ }
221
278
  );
222
279
 
223
280
  /**
@@ -278,8 +335,12 @@ export const __experimentalGetDirtyEntityRecords = createSelector(
278
335
  Object.keys( data[ kind ] ).forEach( ( name ) => {
279
336
  const primaryKeys = Object.keys(
280
337
  data[ kind ][ name ].edits
281
- ).filter( ( primaryKey ) =>
282
- hasEditsForEntityRecord( state, kind, name, primaryKey )
338
+ ).filter(
339
+ ( primaryKey ) =>
340
+ // The entity record must exist (not be deleted),
341
+ // and it must have edits.
342
+ getEntityRecord( state, kind, name, primaryKey ) &&
343
+ hasEditsForEntityRecord( state, kind, name, primaryKey )
283
344
  );
284
345
 
285
346
  if ( primaryKeys.length ) {
@@ -404,7 +465,10 @@ export const getEntityRecordNonTransientEdits = createSelector(
404
465
  return acc;
405
466
  }, {} );
406
467
  },
407
- ( state ) => [ state.entities.config, state.entities.data ]
468
+ ( state, kind, name, recordId ) => [
469
+ state.entities.config,
470
+ get( state.entities.data, [ kind, name, 'edits', recordId ] ),
471
+ ]
408
472
  );
409
473
 
410
474
  /**
@@ -442,7 +506,29 @@ export const getEditedEntityRecord = createSelector(
442
506
  ...getRawEntityRecord( state, kind, name, recordId ),
443
507
  ...getEntityRecordEdits( state, kind, name, recordId ),
444
508
  } ),
445
- ( state ) => [ state.entities.data ]
509
+ ( state, kind, name, recordId, query ) => {
510
+ const context = query?.context ?? 'default';
511
+ return [
512
+ state.entities.config,
513
+ get( state.entities.data, [
514
+ kind,
515
+ name,
516
+ 'queriedData',
517
+ 'items',
518
+ context,
519
+ recordId,
520
+ ] ),
521
+ get( state.entities.data, [
522
+ kind,
523
+ name,
524
+ 'queriedData',
525
+ 'itemIsComplete',
526
+ context,
527
+ recordId,
528
+ ] ),
529
+ get( state.entities.data, [ kind, name, 'edits', recordId ] ),
530
+ ];
531
+ }
446
532
  );
447
533
 
448
534
  /**
@@ -611,7 +697,18 @@ export function hasRedo( state ) {
611
697
  * @return {Object} The current theme.
612
698
  */
613
699
  export function getCurrentTheme( state ) {
614
- return state.themes[ state.currentTheme ];
700
+ return getEntityRecord( state, 'root', 'theme', state.currentTheme );
701
+ }
702
+
703
+ /**
704
+ * Return the ID of the current global styles object.
705
+ *
706
+ * @param {Object} state Data state.
707
+ *
708
+ * @return {string} The current global styles ID.
709
+ */
710
+ export function __experimentalGetCurrentGlobalStylesId( state ) {
711
+ return state.currentGlobalStylesId;
615
712
  }
616
713
 
617
714
  /**
@@ -622,7 +719,7 @@ export function getCurrentTheme( state ) {
622
719
  * @return {*} Index data.
623
720
  */
624
721
  export function getThemeSupports( state ) {
625
- return state.themeSupports;
722
+ return getCurrentTheme( state )?.theme_supports ?? EMPTY_OBJECT;
626
723
  }
627
724
 
628
725
  /**
@@ -809,3 +906,18 @@ export function __experimentalGetTemplateForLink( state, link ) {
809
906
  }
810
907
  return template;
811
908
  }
909
+
910
+ /**
911
+ * Retrieve the current theme's base global styles
912
+ *
913
+ * @param {Object} state Editor state.
914
+ *
915
+ * @return {Object?} The Global Styles object.
916
+ */
917
+ export function __experimentalGetCurrentThemeBaseGlobalStyles( state ) {
918
+ const currentTheme = getCurrentTheme( state );
919
+ if ( ! currentTheme ) {
920
+ return null;
921
+ }
922
+ return state.themeBaseGlobalStyles[ currentTheme.stylesheet ];
923
+ }