@wordpress/core-data 7.41.2-next.v.202603161435.0 → 7.43.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 (161) hide show
  1. package/CHANGELOG.md +3 -1
  2. package/build/awareness/post-editor-awareness.cjs +12 -5
  3. package/build/awareness/post-editor-awareness.cjs.map +2 -2
  4. package/build/entities.cjs +30 -5
  5. package/build/entities.cjs.map +2 -2
  6. package/build/hooks/use-post-editor-awareness-state.cjs +1 -1
  7. package/build/hooks/use-post-editor-awareness-state.cjs.map +2 -2
  8. package/build/private-actions.cjs +10 -0
  9. package/build/private-actions.cjs.map +2 -2
  10. package/build/private-selectors.cjs +20 -3
  11. package/build/private-selectors.cjs.map +2 -2
  12. package/build/queried-data/get-query-parts.cjs +8 -0
  13. package/build/queried-data/get-query-parts.cjs.map +2 -2
  14. package/build/queried-data/reducer.cjs +15 -9
  15. package/build/queried-data/reducer.cjs.map +2 -2
  16. package/build/queried-data/selectors.cjs +10 -2
  17. package/build/queried-data/selectors.cjs.map +2 -2
  18. package/build/reducer.cjs +22 -3
  19. package/build/reducer.cjs.map +2 -2
  20. package/build/resolvers.cjs +16 -8
  21. package/build/resolvers.cjs.map +2 -2
  22. package/build/selectors.cjs +16 -8
  23. package/build/selectors.cjs.map +2 -2
  24. package/build/sync.cjs +3 -0
  25. package/build/sync.cjs.map +2 -2
  26. package/build/types.cjs.map +2 -2
  27. package/build/utils/block-selection-history.cjs +1 -1
  28. package/build/utils/block-selection-history.cjs.map +2 -2
  29. package/build/utils/crdt-blocks.cjs +66 -5
  30. package/build/utils/crdt-blocks.cjs.map +2 -2
  31. package/build/utils/crdt-selection.cjs +4 -1
  32. package/build/utils/crdt-selection.cjs.map +2 -2
  33. package/build/utils/crdt-text.cjs +52 -0
  34. package/build/utils/crdt-text.cjs.map +7 -0
  35. package/build/utils/crdt-user-selections.cjs +1 -1
  36. package/build/utils/crdt-user-selections.cjs.map +2 -2
  37. package/build/utils/crdt-utils.cjs +54 -2
  38. package/build/utils/crdt-utils.cjs.map +2 -2
  39. package/build/utils/crdt.cjs +9 -23
  40. package/build/utils/crdt.cjs.map +2 -2
  41. package/build/utils/index.cjs +0 -3
  42. package/build/utils/index.cjs.map +2 -2
  43. package/build-module/awareness/post-editor-awareness.mjs +12 -5
  44. package/build-module/awareness/post-editor-awareness.mjs.map +2 -2
  45. package/build-module/entities.mjs +30 -5
  46. package/build-module/entities.mjs.map +2 -2
  47. package/build-module/hooks/use-post-editor-awareness-state.mjs +1 -1
  48. package/build-module/hooks/use-post-editor-awareness-state.mjs.map +2 -2
  49. package/build-module/private-actions.mjs +9 -0
  50. package/build-module/private-actions.mjs.map +2 -2
  51. package/build-module/private-selectors.mjs +19 -3
  52. package/build-module/private-selectors.mjs.map +2 -2
  53. package/build-module/queried-data/get-query-parts.mjs +8 -0
  54. package/build-module/queried-data/get-query-parts.mjs.map +2 -2
  55. package/build-module/queried-data/reducer.mjs +15 -9
  56. package/build-module/queried-data/reducer.mjs.map +2 -2
  57. package/build-module/queried-data/selectors.mjs +10 -2
  58. package/build-module/queried-data/selectors.mjs.map +2 -2
  59. package/build-module/reducer.mjs +20 -2
  60. package/build-module/reducer.mjs.map +2 -2
  61. package/build-module/resolvers.mjs +14 -7
  62. package/build-module/resolvers.mjs.map +2 -2
  63. package/build-module/selectors.mjs +16 -9
  64. package/build-module/selectors.mjs.map +2 -2
  65. package/build-module/sync.mjs +2 -0
  66. package/build-module/sync.mjs.map +2 -2
  67. package/build-module/types.mjs.map +2 -2
  68. package/build-module/utils/block-selection-history.mjs +5 -2
  69. package/build-module/utils/block-selection-history.mjs.map +2 -2
  70. package/build-module/utils/crdt-blocks.mjs +65 -5
  71. package/build-module/utils/crdt-blocks.mjs.map +2 -2
  72. package/build-module/utils/crdt-selection.mjs +8 -2
  73. package/build-module/utils/crdt-selection.mjs.map +2 -2
  74. package/build-module/utils/crdt-text.mjs +26 -0
  75. package/build-module/utils/crdt-text.mjs.map +7 -0
  76. package/build-module/utils/crdt-user-selections.mjs +2 -2
  77. package/build-module/utils/crdt-user-selections.mjs.map +2 -2
  78. package/build-module/utils/crdt-utils.mjs +51 -1
  79. package/build-module/utils/crdt-utils.mjs.map +2 -2
  80. package/build-module/utils/crdt.mjs +10 -23
  81. package/build-module/utils/crdt.mjs.map +2 -2
  82. package/build-module/utils/index.mjs +8 -10
  83. package/build-module/utils/index.mjs.map +2 -2
  84. package/build-types/awareness/post-editor-awareness.d.ts +2 -2
  85. package/build-types/awareness/post-editor-awareness.d.ts.map +1 -1
  86. package/build-types/entities.d.ts.map +1 -1
  87. package/build-types/index.d.ts.map +1 -1
  88. package/build-types/private-actions.d.ts +10 -0
  89. package/build-types/private-actions.d.ts.map +1 -1
  90. package/build-types/private-selectors.d.ts +11 -4
  91. package/build-types/private-selectors.d.ts.map +1 -1
  92. package/build-types/queried-data/get-query-parts.d.ts +13 -14
  93. package/build-types/queried-data/get-query-parts.d.ts.map +1 -1
  94. package/build-types/queried-data/reducer.d.ts +11 -5
  95. package/build-types/queried-data/reducer.d.ts.map +1 -1
  96. package/build-types/queried-data/selectors.d.ts.map +1 -1
  97. package/build-types/reducer.d.ts +11 -0
  98. package/build-types/reducer.d.ts.map +1 -1
  99. package/build-types/resolvers.d.ts +3 -0
  100. package/build-types/resolvers.d.ts.map +1 -1
  101. package/build-types/selectors.d.ts +1 -0
  102. package/build-types/selectors.d.ts.map +1 -1
  103. package/build-types/sync.d.ts +2 -2
  104. package/build-types/sync.d.ts.map +1 -1
  105. package/build-types/types.d.ts +4 -2
  106. package/build-types/types.d.ts.map +1 -1
  107. package/build-types/utils/block-selection-history.d.ts.map +1 -1
  108. package/build-types/utils/crdt-blocks.d.ts +11 -0
  109. package/build-types/utils/crdt-blocks.d.ts.map +1 -1
  110. package/build-types/utils/crdt-selection.d.ts.map +1 -1
  111. package/build-types/utils/crdt-text.d.ts +16 -0
  112. package/build-types/utils/crdt-text.d.ts.map +1 -0
  113. package/build-types/utils/crdt-user-selections.d.ts +1 -2
  114. package/build-types/utils/crdt-user-selections.d.ts.map +1 -1
  115. package/build-types/utils/crdt-utils.d.ts +20 -0
  116. package/build-types/utils/crdt-utils.d.ts.map +1 -1
  117. package/build-types/utils/crdt.d.ts +6 -7
  118. package/build-types/utils/crdt.d.ts.map +1 -1
  119. package/build-types/utils/index.d.ts +0 -1
  120. package/build-types/utils/test/crdt-utils.d.ts +2 -0
  121. package/build-types/utils/test/crdt-utils.d.ts.map +1 -0
  122. package/package.json +18 -18
  123. package/src/awareness/post-editor-awareness.ts +13 -6
  124. package/src/awareness/test/post-editor-awareness.ts +15 -10
  125. package/src/entities.js +36 -5
  126. package/src/hooks/test/use-post-editor-awareness-state.ts +3 -3
  127. package/src/hooks/use-post-editor-awareness-state.ts +1 -1
  128. package/src/private-actions.js +18 -0
  129. package/src/private-selectors.ts +37 -4
  130. package/src/queried-data/get-query-parts.js +14 -7
  131. package/src/queried-data/reducer.js +28 -15
  132. package/src/queried-data/selectors.js +11 -3
  133. package/src/queried-data/test/get-query-parts.js +34 -0
  134. package/src/queried-data/test/reducer.js +78 -8
  135. package/src/queried-data/test/selectors.js +171 -0
  136. package/src/reducer.js +31 -0
  137. package/src/resolvers.js +23 -7
  138. package/src/selectors.ts +20 -19
  139. package/src/sync.ts +2 -0
  140. package/src/test/entities.js +185 -1
  141. package/src/types.ts +8 -2
  142. package/src/utils/block-selection-history.ts +5 -2
  143. package/src/utils/crdt-blocks.ts +115 -5
  144. package/src/utils/crdt-selection.ts +8 -2
  145. package/src/utils/crdt-text.ts +43 -0
  146. package/src/utils/crdt-user-selections.ts +13 -13
  147. package/src/utils/crdt-utils.ts +99 -0
  148. package/src/utils/crdt.ts +18 -30
  149. package/src/utils/index.js +0 -1
  150. package/src/utils/test/crdt-blocks.ts +199 -0
  151. package/src/utils/test/crdt-user-selections.ts +5 -0
  152. package/src/utils/test/crdt-utils.ts +387 -0
  153. package/src/utils/test/crdt.ts +229 -54
  154. package/build/utils/is-raw-attribute.cjs +0 -29
  155. package/build/utils/is-raw-attribute.cjs.map +0 -7
  156. package/build-module/utils/is-raw-attribute.mjs +0 -8
  157. package/build-module/utils/is-raw-attribute.mjs.map +0 -7
  158. package/build-types/utils/is-raw-attribute.d.ts +0 -10
  159. package/build-types/utils/is-raw-attribute.d.ts.map +0 -1
  160. package/src/utils/is-raw-attribute.js +0 -11
  161. package/src/utils/test/is-raw-attribute.js +0 -22
@@ -1,6 +1,5 @@
1
1
  import { Y } from '@wordpress/sync';
2
- import type { SelectionDirection } from '../types';
3
- import { type AbsoluteBlockIndexPath, type WPBlockSelection, type SelectionState } from '../types';
2
+ import type { AbsoluteBlockIndexPath, WPBlockSelection, SelectionState, SelectionDirection } from '../types';
4
3
  /**
5
4
  * The type of selection.
6
5
  */
@@ -1 +1 @@
1
- {"version":3,"file":"crdt-user-selections.d.ts","sourceRoot":"","sources":["../../src/utils/crdt-user-selections.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAWpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EACN,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,cAAc,EAOnB,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,oBAAY,aAAa;IACxB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,mBAAmB,2BAA2B;IAC9C,yBAAyB,iCAAiC;IAC1D,UAAU,gBAAgB;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAChC,cAAc,EAAE,gBAAgB,EAChC,YAAY,EAAE,gBAAgB,EAC9B,IAAI,EAAE,CAAC,CAAC,GAAG,EACX,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;CAAE,GACnD,cAAc,CAwFhB;AA0CD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAC3C,QAAQ,EAAE,MAAM,GACd,sBAAsB,GAAG,IAAI,CAyB/B;AA4DD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACvC,UAAU,EAAE,cAAc,EAC1B,UAAU,EAAE,cAAc,GACxB,OAAO,CAsDT"}
1
+ {"version":3,"file":"crdt-user-selections.d.ts","sourceRoot":"","sources":["../../src/utils/crdt-user-selections.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAWpC,OAAO,KAAK,EACX,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EAMd,kBAAkB,EAElB,MAAM,UAAU,CAAC;AAElB;;GAEG;AACH,oBAAY,aAAa;IACxB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,mBAAmB,2BAA2B;IAC9C,yBAAyB,iCAAiC;IAC1D,UAAU,gBAAgB;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAChC,cAAc,EAAE,gBAAgB,EAChC,YAAY,EAAE,gBAAgB,EAC9B,IAAI,EAAE,CAAC,CAAC,GAAG,EACX,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;CAAE,GACnD,cAAc,CAwFhB;AA0CD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAC3C,QAAQ,EAAE,MAAM,GACd,sBAAsB,GAAG,IAAI,CAyB/B;AA4DD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACvC,UAAU,EAAE,cAAc,EAC1B,UAAU,EAAE,cAAc,GACxB,OAAO,CAsDT"}
@@ -62,4 +62,24 @@ export declare function isYMap<T extends YMapRecord>(value: YMapWrap<T> | undefi
62
62
  * @return The block, or null if the block is not found
63
63
  */
64
64
  export declare function findBlockByClientIdInDoc(blockId: string, ydoc: Y.Doc): YBlock | null;
65
+ /**
66
+ * Convert an HTML character index (counting tag characters) to a rich-text
67
+ * offset (counting only text characters). Used on read paths where Y.Text
68
+ * resolves to an HTML index but the block editor expects a text offset.
69
+ *
70
+ * @param html The full HTML string from Y.Text.
71
+ * @param htmlIndex The HTML character index.
72
+ * @return The corresponding rich-text offset.
73
+ */
74
+ export declare function htmlIndexToRichTextOffset(html: string, htmlIndex: number): number;
75
+ /**
76
+ * Convert a rich-text offset (counting only text characters) to an HTML
77
+ * character index (counting tag characters). Used on write paths where the
78
+ * block editor provides a text offset but Y.Text expects an HTML index.
79
+ *
80
+ * @param html The full HTML string from Y.Text.
81
+ * @param richTextOffset The rich-text text offset.
82
+ * @return The corresponding HTML character index.
83
+ */
84
+ export declare function richTextOffsetToHtmlIndex(html: string, richTextOffset: number): number;
65
85
  //# sourceMappingURL=crdt-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crdt-utils.d.ts","sourceRoot":"","sources":["../../src/utils/crdt-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAEpC;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,eAAe,CAAC;AAIrD;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAE,MAAM,EAAE,OAAO,CAAE,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,QAAQ,CAAE,CAAC,SAAS,UAAU,CAAG,SAAQ,CAAC,CAAC,YAAY,CAAE,CAAC,CAAE;IAC5E,MAAM,EAAE,CAAE,CAAC,SAAS,MAAM,CAAC,EAAI,GAAG,EAAE,CAAC,KAAM,IAAI,CAAC;IAChD,OAAO,EAAE,CACR,QAAQ,EAAE,CACT,KAAK,EAAE,CAAC,CAAE,MAAM,CAAC,CAAE,EACnB,GAAG,EAAE,MAAM,CAAC,EACZ,GAAG,EAAE,QAAQ,CAAE,CAAC,CAAE,KACd,IAAI,KACL,IAAI,CAAC;IACV,GAAG,EAAE,CAAE,CAAC,SAAS,MAAM,CAAC,EAAI,GAAG,EAAE,CAAC,KAAM,OAAO,CAAC;IAChD,GAAG,EAAE,CAAE,CAAC,SAAS,MAAM,CAAC,EAAI,GAAG,EAAE,CAAC,KAAM,CAAC,CAAE,CAAC,CAAE,GAAG,SAAS,CAAC;IAC3D,GAAG,EAAE,CAAE,CAAC,SAAS,MAAM,CAAC,EAAI,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAE,CAAC,CAAE,KAAM,IAAI,CAAC;IAC5D,MAAM,EAAE,MAAM,CAAC,CAAC;CAEhB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAE,CAAC,SAAS,UAAU,EAC/C,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,GAAG,EAAE,MAAM,GACT,QAAQ,CAAE,CAAC,CAAE,CAEf;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAE,CAAC,SAAS,UAAU,EAC/C,OAAO,GAAE,OAAO,CAAE,CAAC,CAAO,GACxB,QAAQ,CAAE,CAAC,CAAE,CAEf;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAE,CAAC,SAAS,UAAU,EAC3C,KAAK,EAAE,QAAQ,CAAE,CAAC,CAAE,GAAG,SAAS,GAC9B,KAAK,IAAI,QAAQ,CAAE,CAAC,CAAE,CAExB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,CAAC,CAAC,GAAG,GACT,MAAM,GAAG,IAAI,CASf"}
1
+ {"version":3,"file":"crdt-utils.d.ts","sourceRoot":"","sources":["../../src/utils/crdt-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAC;AAGpC;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,eAAe,CAAC;AAIrD;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAE,MAAM,EAAE,OAAO,CAAE,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,QAAQ,CAAE,CAAC,SAAS,UAAU,CAAG,SAAQ,CAAC,CAAC,YAAY,CAAE,CAAC,CAAE;IAC5E,MAAM,EAAE,CAAE,CAAC,SAAS,MAAM,CAAC,EAAI,GAAG,EAAE,CAAC,KAAM,IAAI,CAAC;IAChD,OAAO,EAAE,CACR,QAAQ,EAAE,CACT,KAAK,EAAE,CAAC,CAAE,MAAM,CAAC,CAAE,EACnB,GAAG,EAAE,MAAM,CAAC,EACZ,GAAG,EAAE,QAAQ,CAAE,CAAC,CAAE,KACd,IAAI,KACL,IAAI,CAAC;IACV,GAAG,EAAE,CAAE,CAAC,SAAS,MAAM,CAAC,EAAI,GAAG,EAAE,CAAC,KAAM,OAAO,CAAC;IAChD,GAAG,EAAE,CAAE,CAAC,SAAS,MAAM,CAAC,EAAI,GAAG,EAAE,CAAC,KAAM,CAAC,CAAE,CAAC,CAAE,GAAG,SAAS,CAAC;IAC3D,GAAG,EAAE,CAAE,CAAC,SAAS,MAAM,CAAC,EAAI,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAE,CAAC,CAAE,KAAM,IAAI,CAAC;IAC5D,MAAM,EAAE,MAAM,CAAC,CAAC;CAEhB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAE,CAAC,SAAS,UAAU,EAC/C,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,GAAG,EAAE,MAAM,GACT,QAAQ,CAAE,CAAC,CAAE,CAEf;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAE,CAAC,SAAS,UAAU,EAC/C,OAAO,GAAE,OAAO,CAAE,CAAC,CAAO,GACxB,QAAQ,CAAE,CAAC,CAAE,CAEf;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAE,CAAC,SAAS,UAAU,EAC3C,KAAK,EAAE,QAAQ,CAAE,CAAC,CAAE,GAAG,SAAS,GAC9B,KAAK,IAAI,QAAQ,CAAE,CAAC,CAAE,CAExB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,CAAC,CAAC,GAAG,GACT,MAAM,GAAG,IAAI,CASf;AA2BD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GACf,MAAM,CAiBR;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,GACpB,MAAM,CA4BR"}
@@ -1,7 +1,6 @@
1
1
  import { type CRDTDoc, type SyncConfig, Y } from '@wordpress/sync';
2
2
  import { type Block, type YBlocks } from './crdt-blocks';
3
3
  import { type Post } from '../entity-types/post';
4
- import { type Type } from '../entity-types';
5
4
  import type { WPSelection } from '../types';
6
5
  import { type YMapRecord, type YMapWrap } from './crdt-utils';
7
6
  export type PostChanges = Partial<Post> & {
@@ -37,21 +36,21 @@ export declare const POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE = "_crdt_document";
37
36
  *
38
37
  * @param {CRDTDoc} ydoc
39
38
  * @param {PostChanges} changes
40
- * @param {Type} _postType
39
+ * @param {Set<string>} syncedProperties
41
40
  * @return {void}
42
41
  */
43
- export declare function applyPostChangesToCRDTDoc(ydoc: CRDTDoc, changes: PostChanges, _postType: Type): void;
42
+ export declare function applyPostChangesToCRDTDoc(ydoc: CRDTDoc, changes: PostChanges, syncedProperties: Set<string>): void;
44
43
  /**
45
44
  * Given a local Y.Doc that *may* contain changes from remote peers, compare
46
45
  * against the local record and determine if there are changes (edits) we want
47
46
  * to dispatch.
48
47
  *
49
- * @param {CRDTDoc} ydoc
50
- * @param {Post} editedRecord
51
- * @param {Type} _postType
48
+ * @param {CRDTDoc} ydoc
49
+ * @param {Post} editedRecord
50
+ * @param {Set<string>} syncedProperties
52
51
  * @return {Partial<PostChanges>} The changes that should be applied to the local record.
53
52
  */
54
- export declare function getPostChangesFromCRDTDoc(ydoc: CRDTDoc, editedRecord: Post, _postType: Type): PostChanges;
53
+ export declare function getPostChangesFromCRDTDoc(ydoc: CRDTDoc, editedRecord: Post, syncedProperties: Set<string>): PostChanges;
55
54
  /**
56
55
  * This default sync config can be used for entities that are flat maps of
57
56
  * primitive values and do not require custom logic to merge changes.
@@ -1 +1 @@
1
- {"version":3,"file":"crdt.d.ts","sourceRoot":"","sources":["../../src/utils/crdt.ts"],"names":[],"mappings":"AAUA,OAAO,EACN,KAAK,OAAO,EAEZ,KAAK,UAAU,EACf,CAAC,EACD,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EAGN,KAAK,KAAK,EAEV,KAAK,OAAO,EACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAM5C,OAAO,EAIN,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,MAAM,cAAc,CAAC;AAGtB,MAAM,MAAM,WAAW,GAAG,OAAO,CAAE,IAAI,CAAE,GAAG;IAC3C,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,IAAI,CAAE,SAAS,CAAE,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,IAAI,CAAE,SAAS,CAAE,GAAG,MAAM,CAAC;IACrC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,KAAK,CAAC,EAAE,IAAI,CAAE,OAAO,CAAE,GAAG,MAAM,CAAC;CACjC,CAAC;AAGF,MAAM,WAAW,WAAY,SAAQ,UAAU;IAC9C,MAAM,EAAE,MAAM,CAAC;IAEf,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAE,UAAU,CAAE,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC;CACd;AAED,eAAO,MAAM,sCAAsC,mBAAmB,CAAC;AA2DvE;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,IAAI,GACb,IAAI,CAoIN;AAMD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,OAAO,EACb,YAAY,EAAE,IAAI,EAClB,SAAS,EAAE,IAAI,GACb,WAAW,CAkIb;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,UAI/B,CAAC"}
1
+ {"version":3,"file":"crdt.d.ts","sourceRoot":"","sources":["../../src/utils/crdt.ts"],"names":[],"mappings":"AAUA,OAAO,EACN,KAAK,OAAO,EAEZ,KAAK,UAAU,EACf,CAAC,EACD,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EAIN,KAAK,KAAK,EAEV,KAAK,OAAO,EACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAM5C,OAAO,EAIN,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,MAAM,cAAc,CAAC;AAGtB,MAAM,MAAM,WAAW,GAAG,OAAO,CAAE,IAAI,CAAE,GAAG;IAC3C,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,IAAI,CAAE,SAAS,CAAE,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,IAAI,CAAE,SAAS,CAAE,GAAG,MAAM,CAAC;IACrC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,KAAK,CAAC,EAAE,IAAI,CAAE,OAAO,CAAE,GAAG,MAAM,CAAC;CACjC,CAAC;AAGF,MAAM,WAAW,WAAY,SAAQ,UAAU;IAC9C,MAAM,EAAE,MAAM,CAAC;IAEf,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAE,UAAU,CAAE,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC;CACd;AAED,eAAO,MAAM,sCAAsC,mBAAmB,CAAC;AAsCvE;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,WAAW,EACpB,gBAAgB,EAAE,GAAG,CAAE,MAAM,CAAE,GAC7B,IAAI,CAoIN;AAMD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,OAAO,EACb,YAAY,EAAE,IAAI,EAClB,gBAAgB,EAAE,GAAG,CAAE,MAAM,CAAE,GAC7B,WAAW,CA2Ib;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,UAI/B,CAAC"}
@@ -5,7 +5,6 @@ export { default as forwardResolver } from "./forward-resolver";
5
5
  export { default as onSubKey } from "./on-sub-key";
6
6
  export { default as replaceAction } from "./replace-action";
7
7
  export { default as withWeakMapCache } from "./with-weak-map-cache";
8
- export { default as isRawAttribute } from "./is-raw-attribute";
9
8
  export { default as setNestedValue } from "./set-nested-value";
10
9
  export { default as getNestedValue } from "./get-nested-value";
11
10
  export { default as isNumericID } from "./is-numeric-id";
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=crdt-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crdt-utils.d.ts","sourceRoot":"","sources":["../../../src/utils/test/crdt-utils.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/core-data",
3
- "version": "7.41.2-next.v.202603161435.0+ab4981c4f",
3
+ "version": "7.43.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",
@@ -49,22 +49,22 @@
49
49
  "build-module/index.mjs"
50
50
  ],
51
51
  "dependencies": {
52
- "@wordpress/api-fetch": "^7.41.1-next.v.202603161435.0+ab4981c4f",
53
- "@wordpress/block-editor": "^15.14.1-next.v.202603161435.0+ab4981c4f",
54
- "@wordpress/blocks": "^15.14.1-next.v.202603161435.0+ab4981c4f",
55
- "@wordpress/compose": "^7.41.1-next.v.202603161435.0+ab4981c4f",
56
- "@wordpress/data": "^10.41.1-next.v.202603161435.0+ab4981c4f",
57
- "@wordpress/deprecated": "^4.41.1-next.v.202603161435.0+ab4981c4f",
58
- "@wordpress/element": "^6.41.1-next.v.202603161435.0+ab4981c4f",
59
- "@wordpress/html-entities": "^4.41.1-next.v.202603161435.0+ab4981c4f",
60
- "@wordpress/i18n": "^6.14.1-next.v.202603161435.0+ab4981c4f",
61
- "@wordpress/is-shallow-equal": "^5.41.1-next.v.202603161435.0+ab4981c4f",
62
- "@wordpress/private-apis": "^1.41.1-next.v.202603161435.0+ab4981c4f",
63
- "@wordpress/rich-text": "^7.41.1-next.v.202603161435.0+ab4981c4f",
64
- "@wordpress/sync": "^1.41.1-next.v.202603161435.0+ab4981c4f",
65
- "@wordpress/undo-manager": "^1.41.1-next.v.202603161435.0+ab4981c4f",
66
- "@wordpress/url": "^4.41.1-next.v.202603161435.0+ab4981c4f",
67
- "@wordpress/warning": "^3.41.1-next.v.202603161435.0+ab4981c4f",
52
+ "@wordpress/api-fetch": "^7.43.0",
53
+ "@wordpress/block-editor": "^15.16.0",
54
+ "@wordpress/blocks": "^15.16.0",
55
+ "@wordpress/compose": "^7.43.0",
56
+ "@wordpress/data": "^10.43.0",
57
+ "@wordpress/deprecated": "^4.43.0",
58
+ "@wordpress/element": "^6.43.0",
59
+ "@wordpress/html-entities": "^4.43.0",
60
+ "@wordpress/i18n": "^6.16.0",
61
+ "@wordpress/is-shallow-equal": "^5.43.0",
62
+ "@wordpress/private-apis": "^1.43.0",
63
+ "@wordpress/rich-text": "^7.43.0",
64
+ "@wordpress/sync": "^1.43.0",
65
+ "@wordpress/undo-manager": "^1.43.0",
66
+ "@wordpress/url": "^4.43.0",
67
+ "@wordpress/warning": "^3.43.0",
68
68
  "change-case": "^4.1.2",
69
69
  "equivalent-key-map": "^0.2.2",
70
70
  "fast-deep-equal": "^3.1.3",
@@ -84,5 +84,5 @@
84
84
  "publishConfig": {
85
85
  "access": "public"
86
86
  },
87
- "gitHead": "748f4e4564fcc0e6ae90200d90bb993a3cef5828"
87
+ "gitHead": "2cea90674d11aa521ec3f71652fb3a6a4c383969"
88
88
  }
@@ -16,6 +16,7 @@ import {
16
16
  LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS,
17
17
  } from './config';
18
18
  import { STORE_NAME as coreStore } from '../name';
19
+ import { htmlIndexToRichTextOffset } from '../utils/crdt-utils';
19
20
  import {
20
21
  areSelectionsStatesEqual,
21
22
  getSelectionState,
@@ -233,14 +234,14 @@ export class PostEditorAwareness extends BaseAwarenessState< PostEditorState > {
233
234
  * clientIds (e.g. in "Show Template" mode where blocks are cloned).
234
235
  *
235
236
  * @param selection - The selection state.
236
- * @return The text index and block client ID, or nulls if not resolvable.
237
+ * @return The rich-text offset and block client ID, or nulls if not resolvable.
237
238
  */
238
239
  public convertSelectionStateToAbsolute( selection: SelectionState ): {
239
- textIndex: number | null;
240
+ richTextOffset: number | null;
240
241
  localClientId: string | null;
241
242
  } {
242
243
  if ( selection.type === SelectionType.None ) {
243
- return { textIndex: null, localClientId: null };
244
+ return { richTextOffset: null, localClientId: null };
244
245
  }
245
246
 
246
247
  if ( selection.type === SelectionType.WholeBlock ) {
@@ -263,7 +264,7 @@ export class PostEditorAwareness extends BaseAwarenessState< PostEditorState > {
263
264
  }
264
265
  }
265
266
 
266
- return { textIndex: null, localClientId };
267
+ return { richTextOffset: null, localClientId };
267
268
  }
268
269
 
269
270
  // Text-based selections: resolve cursor position and navigate up.
@@ -278,7 +279,7 @@ export class PostEditorAwareness extends BaseAwarenessState< PostEditorState > {
278
279
  );
279
280
 
280
281
  if ( ! absolutePosition ) {
281
- return { textIndex: null, localClientId: null };
282
+ return { richTextOffset: null, localClientId: null };
282
283
  }
283
284
 
284
285
  // Navigate up: Y.Text -> attributes Y.Map -> block Y.Map
@@ -287,7 +288,13 @@ export class PostEditorAwareness extends BaseAwarenessState< PostEditorState > {
287
288
  yType instanceof Y.Map ? getBlockPathInYdoc( yType ) : null;
288
289
  const localClientId = path ? resolveBlockClientIdByPath( path ) : null;
289
290
 
290
- return { textIndex: absolutePosition.index, localClientId };
291
+ return {
292
+ richTextOffset: htmlIndexToRichTextOffset(
293
+ absolutePosition.type.toString(),
294
+ absolutePosition.index
295
+ ),
296
+ localClientId,
297
+ };
291
298
  }
292
299
 
293
300
  /**
@@ -23,6 +23,11 @@ jest.mock( '@wordpress/data', () => ( {
23
23
  select: jest.fn(),
24
24
  subscribe: jest.fn(),
25
25
  resolveSelect: jest.fn(),
26
+ // Needed because @wordpress/rich-text initialises its store at import time.
27
+ combineReducers: jest.fn( () => jest.fn( () => ( {} ) ) ),
28
+ createReduxStore: jest.fn( () => ( {} ) ),
29
+ register: jest.fn(),
30
+ createSelector: ( selector: Function ) => selector,
26
31
  } ) );
27
32
 
28
33
  jest.mock( '@wordpress/block-editor', () => ( {
@@ -491,7 +496,7 @@ describe( 'PostEditorAwareness', () => {
491
496
  awareness.convertSelectionStateToAbsolute( selection );
492
497
 
493
498
  // Should return nulls when the relative position's type cannot be found
494
- expect( result.textIndex ).toBeNull();
499
+ expect( result.richTextOffset ).toBeNull();
495
500
  expect( result.localClientId ).toBeNull();
496
501
  } );
497
502
 
@@ -529,7 +534,7 @@ describe( 'PostEditorAwareness', () => {
529
534
  const result =
530
535
  awareness.convertSelectionStateToAbsolute( selection );
531
536
 
532
- expect( result.textIndex ).toBe( 5 );
537
+ expect( result.richTextOffset ).toBe( 5 );
533
538
  expect( result.localClientId ).toBe( 'block-1' );
534
539
  } );
535
540
 
@@ -561,7 +566,7 @@ describe( 'PostEditorAwareness', () => {
561
566
  const result =
562
567
  awareness.convertSelectionStateToAbsolute( selection );
563
568
 
564
- expect( result.textIndex ).toBeNull();
569
+ expect( result.richTextOffset ).toBeNull();
565
570
  expect( result.localClientId ).toBe( 'block-1' );
566
571
  } );
567
572
  } );
@@ -767,7 +772,7 @@ describe( 'PostEditorAwareness', () => {
767
772
  const result =
768
773
  awareness.convertSelectionStateToAbsolute( selection );
769
774
 
770
- expect( result.textIndex ).toBe( 2 );
775
+ expect( result.richTextOffset ).toBe( 2 );
771
776
  expect( result.localClientId ).toBe( 'local-2' );
772
777
 
773
778
  nestedDoc.destroy();
@@ -840,7 +845,7 @@ describe( 'PostEditorAwareness', () => {
840
845
  const result =
841
846
  awareness.convertSelectionStateToAbsolute( selection );
842
847
 
843
- expect( result.textIndex ).toBe( 5 );
848
+ expect( result.richTextOffset ).toBe( 5 );
844
849
  expect( result.localClientId ).toBe( 'local-inner-1' );
845
850
 
846
851
  nestedDoc.destroy();
@@ -895,7 +900,7 @@ describe( 'PostEditorAwareness', () => {
895
900
  const result =
896
901
  awareness.convertSelectionStateToAbsolute( selection );
897
902
 
898
- expect( result.textIndex ).toBeNull();
903
+ expect( result.richTextOffset ).toBeNull();
899
904
  expect( result.localClientId ).toBe( 'local-img' );
900
905
 
901
906
  nestedDoc.destroy();
@@ -989,7 +994,7 @@ describe( 'PostEditorAwareness', () => {
989
994
  const result =
990
995
  awareness.convertSelectionStateToAbsolute( selection );
991
996
 
992
- expect( result.textIndex ).toBe( 7 );
997
+ expect( result.richTextOffset ).toBe( 7 );
993
998
  expect( result.localClientId ).toBe( 'local-deep-1' );
994
999
 
995
1000
  nestedDoc.destroy();
@@ -1090,7 +1095,7 @@ describe( 'PostEditorAwareness', () => {
1090
1095
  const result =
1091
1096
  awareness.convertSelectionStateToAbsolute( selection );
1092
1097
 
1093
- expect( result.textIndex ).toBe( 4 );
1098
+ expect( result.richTextOffset ).toBe( 4 );
1094
1099
  // Should resolve to the post-content inner block, not a template block
1095
1100
  expect( result.localClientId ).toBe( 'local-para-1' );
1096
1101
  // Verify getBlocks was called with the post-content clientId
@@ -1162,7 +1167,7 @@ describe( 'PostEditorAwareness', () => {
1162
1167
  const result =
1163
1168
  awareness.convertSelectionStateToAbsolute( selection );
1164
1169
 
1165
- expect( result.textIndex ).toBeNull();
1170
+ expect( result.richTextOffset ).toBeNull();
1166
1171
  expect( result.localClientId ).toBe( 'local-img' );
1167
1172
 
1168
1173
  templateDoc.destroy();
@@ -1211,7 +1216,7 @@ describe( 'PostEditorAwareness', () => {
1211
1216
  const result =
1212
1217
  awareness.convertSelectionStateToAbsolute( selection );
1213
1218
 
1214
- expect( result.textIndex ).toBe( 3 );
1219
+ expect( result.richTextOffset ).toBe( 3 );
1215
1220
  expect( result.localClientId ).toBe( 'local-para' );
1216
1221
 
1217
1222
  normalDoc.destroy();
package/src/entities.js CHANGED
@@ -329,15 +329,42 @@ export const prePersistPostType = async (
329
329
  * @return {Promise} Entities promise
330
330
  */
331
331
  async function loadPostTypeEntities() {
332
- const postTypes = await apiFetch( {
333
- path: '/wp/v2/types?context=view',
334
- } );
332
+ const postTypesPromise = apiFetch( { path: '/wp/v2/types?context=view' } );
333
+ const taxonomiesPromise = window._wpCollaborationEnabled
334
+ ? apiFetch( { path: '/wp/v2/taxonomies?context=view' } )
335
+ : Promise.resolve( {} );
336
+ const [ postTypes, taxonomies ] = await Promise.all( [
337
+ postTypesPromise,
338
+ taxonomiesPromise,
339
+ ] );
340
+
335
341
  return Object.entries( postTypes ?? {} ).map( ( [ name, postType ] ) => {
336
342
  const isTemplate = [ 'wp_template', 'wp_template_part' ].includes(
337
343
  name
338
344
  );
339
345
  const namespace = postType?.rest_namespace ?? 'wp/v2';
340
346
 
347
+ const syncedProperties = new Set( [
348
+ 'author',
349
+ 'blocks',
350
+ 'content',
351
+ 'comment_status',
352
+ 'date',
353
+ 'excerpt',
354
+ 'featured_media',
355
+ 'format',
356
+ 'meta',
357
+ 'ping_status',
358
+ 'slug',
359
+ 'status',
360
+ 'sticky',
361
+ 'template',
362
+ 'title',
363
+ ...( postType.taxonomies
364
+ ?.map( ( taxonomy ) => taxonomies?.[ taxonomy ]?.rest_base )
365
+ ?.filter( Boolean ) ?? [] ),
366
+ ] );
367
+
341
368
  const entity = {
342
369
  kind: 'postType',
343
370
  baseURL: `/${ namespace }/${ postType.rest_base }`,
@@ -385,7 +412,7 @@ async function loadPostTypeEntities() {
385
412
  * @return {void}
386
413
  */
387
414
  applyChangesToCRDTDoc: ( crdtDoc, changes ) =>
388
- applyPostChangesToCRDTDoc( crdtDoc, changes, postType ),
415
+ applyPostChangesToCRDTDoc( crdtDoc, changes, syncedProperties ),
389
416
 
390
417
  /**
391
418
  * Create the awareness instance for the entity's CRDT document.
@@ -409,7 +436,11 @@ async function loadPostTypeEntities() {
409
436
  * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record
410
437
  */
411
438
  getChangesFromCRDTDoc: ( crdtDoc, editedRecord ) =>
412
- getPostChangesFromCRDTDoc( crdtDoc, editedRecord, postType ),
439
+ getPostChangesFromCRDTDoc(
440
+ crdtDoc,
441
+ editedRecord,
442
+ syncedProperties
443
+ ),
413
444
 
414
445
  /**
415
446
  * Extract changes from a CRDT document that can be used to update the
@@ -293,7 +293,7 @@ describe( 'use-post-editor-awareness-state hooks', () => {
293
293
  };
294
294
 
295
295
  expect( result.current( mockSelection ) ).toEqual( {
296
- textIndex: null,
296
+ richTextOffset: null,
297
297
  localClientId: null,
298
298
  } );
299
299
  } );
@@ -307,7 +307,7 @@ describe( 'use-post-editor-awareness-state hooks', () => {
307
307
  },
308
308
  };
309
309
  mockAwareness.convertSelectionStateToAbsolute.mockReturnValue( {
310
- textIndex: 10,
310
+ richTextOffset: 10,
311
311
  localClientId: 'block-1',
312
312
  } );
313
313
 
@@ -321,7 +321,7 @@ describe( 'use-post-editor-awareness-state hooks', () => {
321
321
  mockAwareness.convertSelectionStateToAbsolute
322
322
  ).toHaveBeenCalledWith( mockSelection );
323
323
  expect( position ).toEqual( {
324
- textIndex: 10,
324
+ richTextOffset: 10,
325
325
  localClientId: 'block-1',
326
326
  } );
327
327
  } );
@@ -25,7 +25,7 @@ interface AwarenessState {
25
25
  }
26
26
 
27
27
  const defaultResolvedSelection: ResolvedSelection = {
28
- textIndex: null,
28
+ richTextOffset: null,
29
29
  localClientId: null,
30
30
  };
31
31
 
@@ -173,3 +173,21 @@ export const setCollaborationSupported =
173
173
  ( { dispatch } ) => {
174
174
  dispatch( { type: 'SET_COLLABORATION_SUPPORTED', supported } );
175
175
  };
176
+
177
+ /**
178
+ * Returns an action object used to receive view config.
179
+ *
180
+ * @param {string} kind Entity kind.
181
+ * @param {string} name Entity name.
182
+ * @param {Object} config View config object.
183
+ *
184
+ * @return {Object} Action object.
185
+ */
186
+ export function receiveViewConfig( kind, name, config ) {
187
+ return {
188
+ type: 'RECEIVE_VIEW_CONFIG',
189
+ kind,
190
+ name,
191
+ config,
192
+ };
193
+ }
@@ -14,6 +14,8 @@ import logEntityDeprecation from './utils/log-entity-deprecation';
14
14
 
15
15
  type EntityRecordKey = string | number;
16
16
 
17
+ const EMPTY_OBJECT = {};
18
+
17
19
  /**
18
20
  * Returns the previous edit from the current undo offset
19
21
  * for the entity records edits history, if any.
@@ -170,11 +172,18 @@ export const getHomePage = createRegistrySelector( ( select ) =>
170
172
  ).getDefaultTemplateId( {
171
173
  slug: 'front-page',
172
174
  } );
173
- // Still resolving getDefaultTemplateId.
174
- if ( ! frontPageTemplateId ) {
175
- return null;
175
+ if ( frontPageTemplateId ) {
176
+ return {
177
+ postType: 'wp_template',
178
+ postId: frontPageTemplateId,
179
+ };
176
180
  }
177
- return { postType: 'wp_template', postId: frontPageTemplateId };
181
+ // Resolution is finished and no front-page template exists.
182
+ if ( frontPageTemplateId === '' ) {
183
+ return EMPTY_OBJECT;
184
+ }
185
+ // Still resolving getDefaultTemplateId.
186
+ return null;
178
187
  },
179
188
  ( state ) => [
180
189
  // Even though getDefaultTemplateId.shouldInvalidate returns true when root/site changes,
@@ -314,3 +323,27 @@ export function getEditorAssets( state: State ): Record< string, any > | null {
314
323
  export function isCollaborationSupported( state: State ): boolean {
315
324
  return state.collaborationSupported;
316
325
  }
326
+
327
+ /**
328
+ * Returns the view configuration for the given entity type.
329
+ *
330
+ * @param state Data state.
331
+ * @param kind Entity kind.
332
+ * @param name Entity name.
333
+ *
334
+ * @return The view configuration or undefined if not loaded.
335
+ */
336
+ export function getViewConfig(
337
+ state: State,
338
+ kind: string,
339
+ name: string
340
+ ): Record< string, any > | undefined {
341
+ return (
342
+ state.viewConfigs?.[ `${ kind }/${ name }` ] ?? {
343
+ default_view: undefined,
344
+ default_layouts: undefined,
345
+ view_list: undefined,
346
+ form: undefined,
347
+ }
348
+ );
349
+ }
@@ -15,13 +15,11 @@ import { withWeakMapCache, getNormalizedCommaSeparable } from '../utils';
15
15
  *
16
16
  * @property {number} page The query page (1-based index, default 1).
17
17
  * @property {number} perPage Items per page for query (default 10).
18
- * @property {string} stableKey An encoded stable string of all non-
19
- * pagination, non-fields query parameters.
20
- * @property {?(string[])} fields Target subset of fields to derive from
21
- * item objects.
22
- * @property {?(number[])} include Specific item IDs to include.
23
- * @property {string} context Scope under which the request is made;
24
- * determines returned fields in response.
18
+ * @property {?number} offset Absolute item offset (default null).
19
+ * @property {string} stableKey An encoded stable string of all non-pagination, non-fields query parameters.
20
+ * @property {?(string[])} fields Target subset of fields to derive from item objects (default null).
21
+ * @property {?(number[])} include Specific item IDs to include (default null).
22
+ * @property {string} context Scope under which the request is made; determines returned fields in response.
25
23
  */
26
24
 
27
25
  /**
@@ -41,6 +39,7 @@ export function getQueryParts( query ) {
41
39
  stableKey: '',
42
40
  page: 1,
43
41
  perPage: 10,
42
+ offset: null,
44
43
  fields: null,
45
44
  include: null,
46
45
  context: 'default',
@@ -62,6 +61,14 @@ export function getQueryParts( query ) {
62
61
  parts.perPage = Number( value );
63
62
  break;
64
63
 
64
+ case 'offset': {
65
+ const numericOffset = Number( value );
66
+ if ( Number.isFinite( numericOffset ) ) {
67
+ parts.offset = numericOffset;
68
+ }
69
+ break;
70
+ }
71
+
65
72
  case 'context':
66
73
  parts.context = value;
67
74
  break;
@@ -30,24 +30,32 @@ function getContextFromAction( action ) {
30
30
  * Returns a merged array of item IDs, given details of the received paginated
31
31
  * items. The array is sparse-like with `undefined` entries where holes exist.
32
32
  *
33
- * @param {?Array<number>} itemIds Original item IDs (default empty array).
34
- * @param {number[]} nextItemIds Item IDs to merge.
35
- * @param {number} page Page of items merged.
36
- * @param {number} perPage Number of items per page.
33
+ * @param {number[]|undefined} itemIds Original item IDs (default empty array).
34
+ * @param {number[]} nextItemIds Item IDs to merge.
35
+ * @param {Object} options Options object.
36
+ * @param {number} [options.page] Page of items merged.
37
+ * @param {number} [options.offset] Offset of items merged.
38
+ * @param {number} options.perPage Number of items per page.
37
39
  *
38
40
  * @return {number[]} Merged array of item IDs.
39
41
  */
40
- export function getMergedItemIds( itemIds, nextItemIds, page, perPage ) {
41
- const receivedAllIds = page === 1 && perPage === -1;
42
- if ( receivedAllIds ) {
42
+ export function getMergedItemIds(
43
+ itemIds = [],
44
+ nextItemIds,
45
+ // The defaults for `page` and `perPage` are the same as in `getQueryParts`.
46
+ { page = 1, offset, perPage = 10 } = {}
47
+ ) {
48
+ // If the query is unbounded, then `nextItemIds` is a complete replacement.
49
+ if ( perPage === -1 ) {
43
50
  return nextItemIds;
44
51
  }
45
- const nextItemIdsStartIndex = ( page - 1 ) * perPage;
52
+
53
+ const nextItemIdsStartIndex = offset ?? ( page - 1 ) * perPage;
46
54
 
47
55
  // If later page has already been received, default to the larger known
48
56
  // size of the existing array, else calculate as extending the existing.
49
57
  const size = Math.max(
50
- itemIds?.length ?? 0,
58
+ itemIds.length,
51
59
  nextItemIdsStartIndex + nextItemIds.length
52
60
  );
53
61
 
@@ -60,9 +68,11 @@ export function getMergedItemIds( itemIds, nextItemIds, page, perPage ) {
60
68
  // a page could receive fewer than what was previously stored.
61
69
  const isInNextItemsRange =
62
70
  i >= nextItemIdsStartIndex && i < nextItemIdsStartIndex + perPage;
63
- mergedItemIds[ i ] = isInNextItemsRange
64
- ? nextItemIds[ i - nextItemIdsStartIndex ]
65
- : itemIds?.[ i ];
71
+ if ( isInNextItemsRange ) {
72
+ mergedItemIds[ i ] = nextItemIds[ i - nextItemIdsStartIndex ];
73
+ } else {
74
+ mergedItemIds[ i ] = itemIds[ i ];
75
+ }
66
76
  }
67
77
 
68
78
  return mergedItemIds;
@@ -244,10 +254,13 @@ const receiveQueries = compose( [
244
254
 
245
255
  return {
246
256
  itemIds: getMergedItemIds(
247
- state?.itemIds || [],
257
+ state.itemIds,
248
258
  action.items.map( ( item ) => item?.[ key ] ).filter( Boolean ),
249
- action.page,
250
- action.perPage
259
+ {
260
+ page: action.page,
261
+ offset: action.offset,
262
+ perPage: action.perPage,
263
+ }
251
264
  ),
252
265
  meta: action.meta,
253
266
  };