@wordpress/core-data 6.18.0 → 6.19.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 (107) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +13 -1
  3. package/build/actions.js +34 -30
  4. package/build/actions.js.map +1 -1
  5. package/build/entity-provider.js +2 -99
  6. package/build/entity-provider.js.map +1 -1
  7. package/build/entity-types/helpers.js.map +1 -1
  8. package/build/footnotes/get-footnotes-order.js +35 -0
  9. package/build/footnotes/get-footnotes-order.js.map +1 -0
  10. package/build/footnotes/get-rich-text-values-cached.js +39 -0
  11. package/build/footnotes/get-rich-text-values-cached.js.map +1 -0
  12. package/build/footnotes/index.js +96 -0
  13. package/build/footnotes/index.js.map +1 -0
  14. package/build/hooks/use-entity-record.js +6 -3
  15. package/build/hooks/use-entity-record.js.map +1 -1
  16. package/build/hooks/use-resource-permissions.js.map +1 -1
  17. package/build/private-selectors.js +4 -17
  18. package/build/private-selectors.js.map +1 -1
  19. package/build/reducer.js +33 -145
  20. package/build/reducer.js.map +1 -1
  21. package/build/resolvers.js +20 -1
  22. package/build/resolvers.js.map +1 -1
  23. package/build/selectors.js +21 -25
  24. package/build/selectors.js.map +1 -1
  25. package/build/utils/get-nested-value.js +30 -0
  26. package/build/utils/get-nested-value.js.map +1 -0
  27. package/build/utils/index.js +7 -0
  28. package/build/utils/index.js.map +1 -1
  29. package/build/utils/set-nested-value.js +11 -6
  30. package/build/utils/set-nested-value.js.map +1 -1
  31. package/build-module/actions.js +32 -28
  32. package/build-module/actions.js.map +1 -1
  33. package/build-module/entity-provider.js +2 -99
  34. package/build-module/entity-provider.js.map +1 -1
  35. package/build-module/entity-types/helpers.js.map +1 -1
  36. package/build-module/footnotes/get-footnotes-order.js +27 -0
  37. package/build-module/footnotes/get-footnotes-order.js.map +1 -0
  38. package/build-module/footnotes/get-rich-text-values-cached.js +33 -0
  39. package/build-module/footnotes/get-rich-text-values-cached.js.map +1 -0
  40. package/build-module/footnotes/index.js +88 -0
  41. package/build-module/footnotes/index.js.map +1 -0
  42. package/build-module/hooks/use-entity-record.js +6 -3
  43. package/build-module/hooks/use-entity-record.js.map +1 -1
  44. package/build-module/hooks/use-resource-permissions.js.map +1 -1
  45. package/build-module/private-selectors.js +3 -15
  46. package/build-module/private-selectors.js.map +1 -1
  47. package/build-module/reducer.js +30 -144
  48. package/build-module/reducer.js.map +1 -1
  49. package/build-module/resolvers.js +18 -0
  50. package/build-module/resolvers.js.map +1 -1
  51. package/build-module/selectors.js +19 -29
  52. package/build-module/selectors.js.map +1 -1
  53. package/build-module/utils/get-nested-value.js +24 -0
  54. package/build-module/utils/get-nested-value.js.map +1 -0
  55. package/build-module/utils/index.js +1 -0
  56. package/build-module/utils/index.js.map +1 -1
  57. package/build-module/utils/set-nested-value.js +11 -6
  58. package/build-module/utils/set-nested-value.js.map +1 -1
  59. package/build-types/actions.d.ts +1 -6
  60. package/build-types/actions.d.ts.map +1 -1
  61. package/build-types/entity-provider.d.ts.map +1 -1
  62. package/build-types/footnotes/get-footnotes-order.d.ts +2 -0
  63. package/build-types/footnotes/get-footnotes-order.d.ts.map +1 -0
  64. package/build-types/footnotes/get-rich-text-values-cached.d.ts +2 -0
  65. package/build-types/footnotes/get-rich-text-values-cached.d.ts.map +1 -0
  66. package/build-types/footnotes/index.d.ts +4 -0
  67. package/build-types/footnotes/index.d.ts.map +1 -0
  68. package/build-types/hooks/use-entity-record.d.ts +2 -0
  69. package/build-types/hooks/use-entity-record.d.ts.map +1 -1
  70. package/build-types/index.d.ts +3 -2
  71. package/build-types/index.d.ts.map +1 -1
  72. package/build-types/private-selectors.d.ts +3 -13
  73. package/build-types/private-selectors.d.ts.map +1 -1
  74. package/build-types/reducer.d.ts +7 -23
  75. package/build-types/reducer.d.ts.map +1 -1
  76. package/build-types/resolvers.d.ts +4 -0
  77. package/build-types/resolvers.d.ts.map +1 -1
  78. package/build-types/selectors.d.ts +19 -14
  79. package/build-types/selectors.d.ts.map +1 -1
  80. package/build-types/utils/get-nested-value.d.ts +14 -0
  81. package/build-types/utils/get-nested-value.d.ts.map +1 -0
  82. package/build-types/utils/index.d.ts +1 -0
  83. package/build-types/utils/set-nested-value.d.ts +8 -4
  84. package/build-types/utils/set-nested-value.d.ts.map +1 -1
  85. package/package.json +16 -15
  86. package/src/actions.js +36 -26
  87. package/src/entity-provider.js +2 -134
  88. package/src/entity-types/helpers.ts +2 -2
  89. package/src/footnotes/get-footnotes-order.js +30 -0
  90. package/src/footnotes/get-rich-text-values-cached.js +35 -0
  91. package/src/footnotes/index.js +119 -0
  92. package/src/hooks/test/use-entity-record.js +4 -0
  93. package/src/hooks/use-entity-record.ts +12 -3
  94. package/src/hooks/use-resource-permissions.ts +1 -1
  95. package/src/private-selectors.ts +4 -17
  96. package/src/reducer.js +36 -155
  97. package/src/resolvers.js +25 -0
  98. package/src/selectors.ts +39 -51
  99. package/src/test/reducer.js +0 -233
  100. package/src/test/selectors.js +0 -54
  101. package/src/utils/get-nested-value.js +27 -0
  102. package/src/utils/index.js +1 -0
  103. package/src/utils/set-nested-value.js +12 -6
  104. package/src/utils/test/get-nested-value.js +61 -0
  105. package/src/utils/test/set-nested-value.js +7 -0
  106. package/tsconfig.json +1 -0
  107. package/tsconfig.tsbuildinfo +1 -1
package/src/reducer.js CHANGED
@@ -8,7 +8,7 @@ import fastDeepEqual from 'fast-deep-equal/es6';
8
8
  */
9
9
  import { compose } from '@wordpress/compose';
10
10
  import { combineReducers } from '@wordpress/data';
11
- import isShallowEqual from '@wordpress/is-shallow-equal';
11
+ import { createUndoManager } from '@wordpress/undo-manager';
12
12
 
13
13
  /**
14
14
  * Internal dependencies
@@ -185,22 +185,25 @@ export function themeGlobalStyleVariations( state = {}, action ) {
185
185
 
186
186
  const withMultiEntityRecordEdits = ( reducer ) => ( state, action ) => {
187
187
  if ( action.type === 'UNDO' || action.type === 'REDO' ) {
188
- const { stackedEdits } = action;
188
+ const { record } = action;
189
189
 
190
190
  let newState = state;
191
- stackedEdits.forEach(
192
- ( { kind, name, recordId, property, from, to } ) => {
193
- newState = reducer( newState, {
194
- type: 'EDIT_ENTITY_RECORD',
195
- kind,
196
- name,
197
- recordId,
198
- edits: {
199
- [ property ]: action.type === 'UNDO' ? from : to,
191
+ record.forEach( ( { id: { kind, name, recordId }, changes } ) => {
192
+ newState = reducer( newState, {
193
+ type: 'EDIT_ENTITY_RECORD',
194
+ kind,
195
+ name,
196
+ recordId,
197
+ edits: Object.entries( changes ).reduce(
198
+ ( acc, [ key, value ] ) => {
199
+ acc[ key ] =
200
+ action.type === 'UNDO' ? value.from : value.to;
201
+ return acc;
200
202
  },
201
- } );
202
- }
203
- );
203
+ {}
204
+ ),
205
+ } );
206
+ } );
204
207
  return newState;
205
208
  }
206
209
 
@@ -435,151 +438,19 @@ export const entities = ( state = {}, action ) => {
435
438
  };
436
439
 
437
440
  /**
438
- * @typedef {Object} UndoStateMeta
439
- *
440
- * @property {number} list The undo stack.
441
- * @property {number} offset Where in the undo stack we are.
442
- * @property {Object} cache Cache of unpersisted edits.
443
- */
444
-
445
- /** @typedef {Array<Object> & UndoStateMeta} UndoState */
446
-
447
- /**
448
- * @type {UndoState}
449
- *
450
- * @todo Given how we use this we might want to make a custom class for it.
451
- */
452
- const UNDO_INITIAL_STATE = { list: [], offset: 0 };
453
-
454
- /**
455
- * Reducer keeping track of entity edit undo history.
456
- *
457
- * @param {UndoState} state Current state.
458
- * @param {Object} action Dispatched action.
459
- *
460
- * @return {UndoState} Updated state.
441
+ * @type {UndoManager}
461
442
  */
462
- export function undo( state = UNDO_INITIAL_STATE, action ) {
463
- const omitPendingRedos = ( currentState ) => {
464
- return {
465
- ...currentState,
466
- list: currentState.list.slice(
467
- 0,
468
- currentState.offset || undefined
469
- ),
470
- offset: 0,
471
- };
472
- };
473
-
474
- const appendCachedEditsToLastUndo = ( currentState ) => {
475
- if ( ! currentState.cache ) {
476
- return currentState;
477
- }
478
-
479
- let nextState = {
480
- ...currentState,
481
- list: [ ...currentState.list ],
482
- };
483
- nextState = omitPendingRedos( nextState );
484
- const previousUndoState = nextState.list.pop();
485
- const updatedUndoState = currentState.cache.reduce(
486
- appendEditToStack,
487
- previousUndoState
488
- );
489
- nextState.list.push( updatedUndoState );
490
-
491
- return {
492
- ...nextState,
493
- cache: undefined,
494
- };
495
- };
496
-
497
- const appendEditToStack = (
498
- stack = [],
499
- { kind, name, recordId, property, from, to }
500
- ) => {
501
- const existingEditIndex = stack?.findIndex(
502
- ( { kind: k, name: n, recordId: r, property: p } ) => {
503
- return (
504
- k === kind && n === name && r === recordId && p === property
505
- );
506
- }
507
- );
508
- const nextStack = [ ...stack ];
509
- if ( existingEditIndex !== -1 ) {
510
- // If the edit is already in the stack leave the initial "from" value.
511
- nextStack[ existingEditIndex ] = {
512
- ...nextStack[ existingEditIndex ],
513
- to,
514
- };
515
- } else {
516
- nextStack.push( {
517
- kind,
518
- name,
519
- recordId,
520
- property,
521
- from,
522
- to,
523
- } );
524
- }
525
- return nextStack;
526
- };
443
+ export function undoManager( state = createUndoManager() ) {
444
+ return state;
445
+ }
527
446
 
447
+ export function editsReference( state = {}, action ) {
528
448
  switch ( action.type ) {
529
- case 'CREATE_UNDO_LEVEL':
530
- return appendCachedEditsToLastUndo( state );
531
-
449
+ case 'EDIT_ENTITY_RECORD':
532
450
  case 'UNDO':
533
- case 'REDO': {
534
- const nextState = appendCachedEditsToLastUndo( state );
535
- return {
536
- ...nextState,
537
- offset: state.offset + ( action.type === 'UNDO' ? -1 : 1 ),
538
- };
539
- }
540
-
541
- case 'EDIT_ENTITY_RECORD': {
542
- if ( ! action.meta.undo ) {
543
- return state;
544
- }
545
-
546
- const edits = Object.keys( action.edits ).map( ( key ) => {
547
- return {
548
- kind: action.kind,
549
- name: action.name,
550
- recordId: action.recordId,
551
- property: key,
552
- from: action.meta.undo.edits[ key ],
553
- to: action.edits[ key ],
554
- };
555
- } );
556
-
557
- if ( action.meta.undo.isCached ) {
558
- return {
559
- ...state,
560
- cache: edits.reduce( appendEditToStack, state.cache ),
561
- };
562
- }
563
-
564
- let nextState = omitPendingRedos( state );
565
- nextState = appendCachedEditsToLastUndo( nextState );
566
- nextState = { ...nextState, list: [ ...nextState.list ] };
567
- // When an edit is a function it's an optimization to avoid running some expensive operation.
568
- // We can't rely on the function references being the same so we opt out of comparing them here.
569
- const comparisonUndoEdits = Object.values(
570
- action.meta.undo.edits
571
- ).filter( ( edit ) => typeof edit !== 'function' );
572
- const comparisonEdits = Object.values( action.edits ).filter(
573
- ( edit ) => typeof edit !== 'function'
574
- );
575
- if ( ! isShallowEqual( comparisonUndoEdits, comparisonEdits ) ) {
576
- nextState.list.push( edits );
577
- }
578
-
579
- return nextState;
580
- }
451
+ case 'REDO':
452
+ return {};
581
453
  }
582
-
583
454
  return state;
584
455
  }
585
456
 
@@ -664,6 +535,14 @@ export function blockPatternCategories( state = [], action ) {
664
535
  return state;
665
536
  }
666
537
 
538
+ export function userPatternCategories( state = [], action ) {
539
+ switch ( action.type ) {
540
+ case 'RECEIVE_USER_PATTERN_CATEGORIES':
541
+ return action.patternCategories;
542
+ }
543
+ return state;
544
+ }
545
+
667
546
  export function navigationFallbackId( state = null, action ) {
668
547
  switch ( action.type ) {
669
548
  case 'RECEIVE_NAVIGATION_FALLBACK_ID':
@@ -704,11 +583,13 @@ export default combineReducers( {
704
583
  themeGlobalStyleRevisions,
705
584
  taxonomies,
706
585
  entities,
707
- undo,
586
+ editsReference,
587
+ undoManager,
708
588
  embedPreviews,
709
589
  userPermissions,
710
590
  autosaves,
711
591
  blockPatterns,
712
592
  blockPatternCategories,
593
+ userPatternCategories,
713
594
  navigationFallbackId,
714
595
  } );
package/src/resolvers.js CHANGED
@@ -619,6 +619,31 @@ export const getBlockPatternCategories =
619
619
  dispatch( { type: 'RECEIVE_BLOCK_PATTERN_CATEGORIES', categories } );
620
620
  };
621
621
 
622
+ export const getUserPatternCategories =
623
+ () =>
624
+ async ( { dispatch, resolveSelect } ) => {
625
+ const patternCategories = await resolveSelect.getEntityRecords(
626
+ 'taxonomy',
627
+ 'wp_pattern_category',
628
+ {
629
+ per_page: -1,
630
+ _fields: 'id,name,description,slug',
631
+ }
632
+ );
633
+
634
+ const mappedPatternCategories =
635
+ patternCategories?.map( ( userCategory ) => ( {
636
+ ...userCategory,
637
+ label: userCategory.name,
638
+ name: userCategory.slug,
639
+ } ) ) || [];
640
+
641
+ dispatch( {
642
+ type: 'RECEIVE_USER_PATTERN_CATEGORIES',
643
+ patternCategories: mappedPatternCategories,
644
+ } );
645
+ };
646
+
622
647
  export const getNavigationFallbackId =
623
648
  () =>
624
649
  async ( { dispatch, select } ) => {
package/src/selectors.ts CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  setNestedValue,
23
23
  } from './utils';
24
24
  import type * as ET from './entity-types';
25
- import { getUndoEdits, getRedoEdits } from './private-selectors';
25
+ import type { UndoManager } from '@wordpress/undo-manager';
26
26
 
27
27
  // This is an incomplete, high-level approximation of the State type.
28
28
  // It makes the selectors slightly more safe, but is intended to evolve
@@ -40,10 +40,11 @@ export interface State {
40
40
  themeBaseGlobalStyles: Record< string, Object >;
41
41
  themeGlobalStyleVariations: Record< string, string >;
42
42
  themeGlobalStyleRevisions: Record< number, Object >;
43
- undo: UndoState;
43
+ undoManager: UndoManager;
44
44
  userPermissions: Record< string, boolean >;
45
45
  users: UserState;
46
46
  navigationFallbackId: EntityRecordKey;
47
+ userPatternCategories: Array< UserPatternCategory >;
47
48
  }
48
49
 
49
50
  type EntityRecordKey = string | number;
@@ -74,25 +75,19 @@ interface EntityConfig {
74
75
  kind: string;
75
76
  }
76
77
 
77
- export interface UndoEdit {
78
- name: string;
79
- kind: string;
80
- recordId: string;
81
- from: any;
82
- to: any;
83
- }
84
-
85
- interface UndoState {
86
- list: Array< UndoEdit[] >;
87
- offset: number;
88
- cache: UndoEdit[];
89
- }
90
-
91
78
  interface UserState {
92
79
  queries: Record< string, EntityRecordKey[] >;
93
80
  byId: Record< EntityRecordKey, ET.User< 'edit' > >;
94
81
  }
95
82
 
83
+ export interface UserPatternCategory {
84
+ id: number;
85
+ name: string;
86
+ label: string;
87
+ slug: string;
88
+ description: string;
89
+ }
90
+
96
91
  type Optional< T > = T | undefined;
97
92
 
98
93
  /**
@@ -278,7 +273,7 @@ export interface GetEntityRecord {
278
273
  <
279
274
  EntityRecord extends
280
275
  | ET.EntityRecord< any >
281
- | Partial< ET.EntityRecord< any > >
276
+ | Partial< ET.EntityRecord< any > >,
282
277
  >(
283
278
  state: State,
284
279
  kind: string,
@@ -290,7 +285,7 @@ export interface GetEntityRecord {
290
285
  CurriedSignature: <
291
286
  EntityRecord extends
292
287
  | ET.EntityRecord< any >
293
- | Partial< ET.EntityRecord< any > >
288
+ | Partial< ET.EntityRecord< any > >,
294
289
  >(
295
290
  kind: string,
296
291
  name: string,
@@ -317,7 +312,7 @@ export const getEntityRecord = createSelector(
317
312
  ( <
318
313
  EntityRecord extends
319
314
  | ET.EntityRecord< any >
320
- | Partial< ET.EntityRecord< any > >
315
+ | Partial< ET.EntityRecord< any > >,
321
316
  >(
322
317
  state: State,
323
318
  kind: string,
@@ -381,7 +376,7 @@ export const getEntityRecord = createSelector(
381
376
  * @return Record.
382
377
  */
383
378
  export function __experimentalGetEntityRecordNoResolver<
384
- EntityRecord extends ET.EntityRecord< any >
379
+ EntityRecord extends ET.EntityRecord< any >,
385
380
  >( state: State, kind: string, name: string, key: EntityRecordKey ) {
386
381
  return getEntityRecord< EntityRecord >( state, kind, name, key );
387
382
  }
@@ -478,7 +473,7 @@ export interface GetEntityRecords {
478
473
  <
479
474
  EntityRecord extends
480
475
  | ET.EntityRecord< any >
481
- | Partial< ET.EntityRecord< any > >
476
+ | Partial< ET.EntityRecord< any > >,
482
477
  >(
483
478
  state: State,
484
479
  kind: string,
@@ -489,7 +484,7 @@ export interface GetEntityRecords {
489
484
  CurriedSignature: <
490
485
  EntityRecord extends
491
486
  | ET.EntityRecord< any >
492
- | Partial< ET.EntityRecord< any > >
487
+ | Partial< ET.EntityRecord< any > >,
493
488
  >(
494
489
  kind: string,
495
490
  name: string,
@@ -511,7 +506,7 @@ export interface GetEntityRecords {
511
506
  export const getEntityRecords = ( <
512
507
  EntityRecord extends
513
508
  | ET.EntityRecord< any >
514
- | Partial< ET.EntityRecord< any > >
509
+ | Partial< ET.EntityRecord< any > >,
515
510
  >(
516
511
  state: State,
517
512
  kind: string,
@@ -875,21 +870,6 @@ export function getLastEntityDeleteError(
875
870
  ?.error;
876
871
  }
877
872
 
878
- /**
879
- * Returns the current undo offset for the
880
- * entity records edits history. The offset
881
- * represents how many items from the end
882
- * of the history stack we are at. 0 is the
883
- * last edit, -1 is the second last, and so on.
884
- *
885
- * @param state State tree.
886
- *
887
- * @return The current undo offset.
888
- */
889
- function getCurrentUndoOffset( state: State ): number {
890
- return state.undo.offset;
891
- }
892
-
893
873
  /**
894
874
  * Returns the previous edit from the current undo offset
895
875
  * for the entity records edits history, if any.
@@ -904,9 +884,7 @@ export function getUndoEdit( state: State ): Optional< any > {
904
884
  deprecated( "select( 'core' ).getUndoEdit()", {
905
885
  since: '6.3',
906
886
  } );
907
- return state.undo.list[
908
- state.undo.list.length - 2 + getCurrentUndoOffset( state )
909
- ]?.[ 0 ];
887
+ return undefined;
910
888
  }
911
889
 
912
890
  /**
@@ -923,9 +901,7 @@ export function getRedoEdit( state: State ): Optional< any > {
923
901
  deprecated( "select( 'core' ).getRedoEdit()", {
924
902
  since: '6.3',
925
903
  } );
926
- return state.undo.list[
927
- state.undo.list.length + getCurrentUndoOffset( state )
928
- ]?.[ 0 ];
904
+ return undefined;
929
905
  }
930
906
 
931
907
  /**
@@ -937,7 +913,7 @@ export function getRedoEdit( state: State ): Optional< any > {
937
913
  * @return Whether there is a previous edit or not.
938
914
  */
939
915
  export function hasUndo( state: State ): boolean {
940
- return Boolean( getUndoEdits( state ) );
916
+ return state.undoManager.hasUndo();
941
917
  }
942
918
 
943
919
  /**
@@ -949,7 +925,7 @@ export function hasUndo( state: State ): boolean {
949
925
  * @return Whether there is a next edit or not.
950
926
  */
951
927
  export function hasRedo( state: State ): boolean {
952
- return Boolean( getRedoEdits( state ) );
928
+ return state.undoManager.hasRedo();
953
929
  }
954
930
 
955
931
  /**
@@ -1163,11 +1139,9 @@ export const hasFetchedAutosaves = createRegistrySelector(
1163
1139
  *
1164
1140
  * @return A value whose reference will change only when an edit occurs.
1165
1141
  */
1166
- export const getReferenceByDistinctEdits = createSelector(
1167
- // This unused state argument is listed here for the documentation generating tool (docgen).
1168
- ( state: State ) => [],
1169
- ( state: State ) => [ state.undo.list.length, state.undo.offset ]
1170
- );
1142
+ export function getReferenceByDistinctEdits( state ) {
1143
+ return state.editsReference;
1144
+ }
1171
1145
 
1172
1146
  /**
1173
1147
  * Retrieve the frontend template used for a given link.
@@ -1257,6 +1231,20 @@ export function getBlockPatternCategories( state: State ): Array< any > {
1257
1231
  return state.blockPatternCategories;
1258
1232
  }
1259
1233
 
1234
+ /**
1235
+ * Retrieve the registered user pattern categories.
1236
+ *
1237
+ * @param state Data state.
1238
+ *
1239
+ * @return User patterns category array.
1240
+ */
1241
+
1242
+ export function getUserPatternCategories(
1243
+ state: State
1244
+ ): Array< UserPatternCategory > {
1245
+ return state.userPatternCategories;
1246
+ }
1247
+
1260
1248
  /**
1261
1249
  * Returns the revisions of the current global styles theme.
1262
1250
  *