@wordpress/core-data 7.40.2-next.v.202602271551.0 → 7.40.2

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 (182) hide show
  1. package/README.md +0 -27
  2. package/build/actions.cjs +9 -26
  3. package/build/actions.cjs.map +2 -2
  4. package/build/awareness/post-editor-awareness.cjs +45 -6
  5. package/build/awareness/post-editor-awareness.cjs.map +2 -2
  6. package/build/awareness/types.cjs.map +1 -1
  7. package/build/entities.cjs +36 -16
  8. package/build/entities.cjs.map +2 -2
  9. package/build/entity-provider.cjs +15 -6
  10. package/build/entity-provider.cjs.map +2 -2
  11. package/build/hooks/use-entity-prop.cjs +33 -2
  12. package/build/hooks/use-entity-prop.cjs.map +2 -2
  13. package/build/hooks/use-post-editor-awareness-state.cjs +120 -1
  14. package/build/hooks/use-post-editor-awareness-state.cjs.map +2 -2
  15. package/build/index.cjs +0 -3
  16. package/build/index.cjs.map +2 -2
  17. package/build/private-actions.cjs +27 -3
  18. package/build/private-actions.cjs.map +2 -2
  19. package/build/private-apis.cjs +14 -5
  20. package/build/private-apis.cjs.map +3 -3
  21. package/build/private-selectors.cjs +22 -2
  22. package/build/private-selectors.cjs.map +2 -2
  23. package/build/queried-data/actions.cjs +1 -1
  24. package/build/queried-data/actions.cjs.map +2 -2
  25. package/build/queried-data/reducer.cjs +19 -13
  26. package/build/queried-data/reducer.cjs.map +2 -2
  27. package/build/reducer.cjs +19 -2
  28. package/build/reducer.cjs.map +2 -2
  29. package/build/resolvers.cjs +24 -17
  30. package/build/resolvers.cjs.map +2 -2
  31. package/build/selectors.cjs +0 -15
  32. package/build/selectors.cjs.map +2 -2
  33. package/build/sync.cjs +12 -3
  34. package/build/sync.cjs.map +2 -2
  35. package/build/types.cjs.map +1 -1
  36. package/build/utils/block-selection-history.cjs +1 -1
  37. package/build/utils/block-selection-history.cjs.map +2 -2
  38. package/build/utils/crdt-blocks.cjs +85 -28
  39. package/build/utils/crdt-blocks.cjs.map +2 -2
  40. package/build/utils/crdt-selection.cjs +4 -1
  41. package/build/utils/crdt-selection.cjs.map +2 -2
  42. package/build/utils/crdt-text.cjs +52 -0
  43. package/build/utils/crdt-text.cjs.map +7 -0
  44. package/build/utils/crdt-user-selections.cjs +16 -6
  45. package/build/utils/crdt-user-selections.cjs.map +3 -3
  46. package/build/utils/crdt-utils.cjs +54 -2
  47. package/build/utils/crdt-utils.cjs.map +2 -2
  48. package/build/utils/crdt.cjs +26 -28
  49. package/build/utils/crdt.cjs.map +2 -2
  50. package/build-module/actions.mjs +14 -26
  51. package/build-module/actions.mjs.map +2 -2
  52. package/build-module/awareness/post-editor-awareness.mjs +47 -7
  53. package/build-module/awareness/post-editor-awareness.mjs.map +2 -2
  54. package/build-module/entities.mjs +37 -16
  55. package/build-module/entities.mjs.map +2 -2
  56. package/build-module/entity-provider.mjs +15 -6
  57. package/build-module/entity-provider.mjs.map +2 -2
  58. package/build-module/hooks/use-entity-prop.mjs +34 -3
  59. package/build-module/hooks/use-entity-prop.mjs.map +2 -2
  60. package/build-module/hooks/use-post-editor-awareness-state.mjs +117 -1
  61. package/build-module/hooks/use-post-editor-awareness-state.mjs.map +2 -2
  62. package/build-module/index.mjs +0 -2
  63. package/build-module/index.mjs.map +2 -2
  64. package/build-module/private-actions.mjs +24 -2
  65. package/build-module/private-actions.mjs.map +2 -2
  66. package/build-module/private-apis.mjs +21 -6
  67. package/build-module/private-apis.mjs.map +3 -3
  68. package/build-module/private-selectors.mjs +19 -1
  69. package/build-module/private-selectors.mjs.map +2 -2
  70. package/build-module/queried-data/actions.mjs +1 -1
  71. package/build-module/queried-data/actions.mjs.map +2 -2
  72. package/build-module/queried-data/reducer.mjs +19 -13
  73. package/build-module/queried-data/reducer.mjs.map +2 -2
  74. package/build-module/reducer.mjs +18 -2
  75. package/build-module/reducer.mjs.map +2 -2
  76. package/build-module/resolvers.mjs +24 -17
  77. package/build-module/resolvers.mjs.map +2 -2
  78. package/build-module/selectors.mjs +0 -14
  79. package/build-module/selectors.mjs.map +2 -2
  80. package/build-module/sync.mjs +8 -2
  81. package/build-module/sync.mjs.map +2 -2
  82. package/build-module/utils/block-selection-history.mjs +5 -2
  83. package/build-module/utils/block-selection-history.mjs.map +2 -2
  84. package/build-module/utils/crdt-blocks.mjs +84 -28
  85. package/build-module/utils/crdt-blocks.mjs.map +2 -2
  86. package/build-module/utils/crdt-selection.mjs +8 -2
  87. package/build-module/utils/crdt-selection.mjs.map +2 -2
  88. package/build-module/utils/crdt-text.mjs +26 -0
  89. package/build-module/utils/crdt-text.mjs.map +7 -0
  90. package/build-module/utils/crdt-user-selections.mjs +16 -7
  91. package/build-module/utils/crdt-user-selections.mjs.map +3 -3
  92. package/build-module/utils/crdt-utils.mjs +51 -1
  93. package/build-module/utils/crdt-utils.mjs.map +2 -2
  94. package/build-module/utils/crdt.mjs +26 -28
  95. package/build-module/utils/crdt.mjs.map +2 -2
  96. package/build-types/actions.d.ts +0 -11
  97. package/build-types/actions.d.ts.map +1 -1
  98. package/build-types/awareness/post-editor-awareness.d.ts +2 -2
  99. package/build-types/awareness/post-editor-awareness.d.ts.map +1 -1
  100. package/build-types/awareness/types.d.ts +6 -1
  101. package/build-types/awareness/types.d.ts.map +1 -1
  102. package/build-types/entities.d.ts +20 -1
  103. package/build-types/entities.d.ts.map +1 -1
  104. package/build-types/entity-provider.d.ts +11 -6
  105. package/build-types/entity-provider.d.ts.map +1 -1
  106. package/build-types/hooks/use-entity-prop.d.ts.map +1 -1
  107. package/build-types/hooks/use-post-editor-awareness-state.d.ts +40 -7
  108. package/build-types/hooks/use-post-editor-awareness-state.d.ts.map +1 -1
  109. package/build-types/index.d.ts +0 -3
  110. package/build-types/index.d.ts.map +1 -1
  111. package/build-types/parsed-blocks-cache.d.ts +10 -0
  112. package/build-types/parsed-blocks-cache.d.ts.map +1 -0
  113. package/build-types/private-actions.d.ts +12 -0
  114. package/build-types/private-actions.d.ts.map +1 -1
  115. package/build-types/private-apis.d.ts +21 -1
  116. package/build-types/private-apis.d.ts.map +1 -1
  117. package/build-types/private-selectors.d.ts +17 -0
  118. package/build-types/private-selectors.d.ts.map +1 -1
  119. package/build-types/queried-data/reducer.d.ts.map +1 -1
  120. package/build-types/reducer.d.ts +15 -0
  121. package/build-types/reducer.d.ts.map +1 -1
  122. package/build-types/resolvers.d.ts.map +1 -1
  123. package/build-types/selectors.d.ts +1 -9
  124. package/build-types/selectors.d.ts.map +1 -1
  125. package/build-types/sync.d.ts +2 -2
  126. package/build-types/sync.d.ts.map +1 -1
  127. package/build-types/types.d.ts +10 -2
  128. package/build-types/types.d.ts.map +1 -1
  129. package/build-types/utils/block-selection-history.d.ts.map +1 -1
  130. package/build-types/utils/crdt-blocks.d.ts +11 -0
  131. package/build-types/utils/crdt-blocks.d.ts.map +1 -1
  132. package/build-types/utils/crdt-selection.d.ts.map +1 -1
  133. package/build-types/utils/crdt-text.d.ts +16 -0
  134. package/build-types/utils/crdt-text.d.ts.map +1 -0
  135. package/build-types/utils/crdt-user-selections.d.ts +17 -4
  136. package/build-types/utils/crdt-user-selections.d.ts.map +1 -1
  137. package/build-types/utils/crdt-utils.d.ts +20 -0
  138. package/build-types/utils/crdt-utils.d.ts.map +1 -1
  139. package/build-types/utils/crdt.d.ts +13 -7
  140. package/build-types/utils/crdt.d.ts.map +1 -1
  141. package/build-types/utils/normalize-query-for-resolution.d.ts +12 -0
  142. package/build-types/utils/normalize-query-for-resolution.d.ts.map +1 -0
  143. package/build-types/utils/save-crdt-doc.d.ts +8 -0
  144. package/build-types/utils/save-crdt-doc.d.ts.map +1 -0
  145. package/build-types/utils/test/crdt-utils.d.ts +2 -0
  146. package/build-types/utils/test/crdt-utils.d.ts.map +1 -0
  147. package/package.json +18 -18
  148. package/src/actions.js +26 -41
  149. package/src/awareness/post-editor-awareness.ts +106 -7
  150. package/src/awareness/test/post-editor-awareness.ts +50 -10
  151. package/src/awareness/types.ts +7 -1
  152. package/src/entities.js +43 -17
  153. package/src/entity-provider.js +24 -11
  154. package/src/hooks/test/use-post-editor-awareness-state.ts +446 -3
  155. package/src/hooks/use-entity-prop.js +43 -3
  156. package/src/hooks/use-post-editor-awareness-state.ts +229 -7
  157. package/src/index.js +0 -6
  158. package/src/private-actions.js +43 -1
  159. package/src/{private-apis.js → private-apis.ts} +21 -3
  160. package/src/private-selectors.ts +43 -0
  161. package/src/queried-data/actions.js +1 -1
  162. package/src/queried-data/reducer.js +26 -14
  163. package/src/reducer.js +36 -1
  164. package/src/resolvers.js +33 -23
  165. package/src/selectors.ts +1 -32
  166. package/src/sync.ts +6 -0
  167. package/src/test/entities.js +204 -16
  168. package/src/test/private-actions.js +1 -1
  169. package/src/test/resolvers.js +144 -57
  170. package/src/test/store.js +116 -0
  171. package/src/types.ts +20 -2
  172. package/src/utils/block-selection-history.ts +5 -2
  173. package/src/utils/crdt-blocks.ts +159 -56
  174. package/src/utils/crdt-selection.ts +8 -2
  175. package/src/utils/crdt-text.ts +43 -0
  176. package/src/utils/crdt-user-selections.ts +29 -8
  177. package/src/utils/crdt-utils.ts +99 -0
  178. package/src/utils/crdt.ts +50 -40
  179. package/src/utils/test/crdt-blocks.ts +588 -24
  180. package/src/utils/test/crdt-user-selections.ts +5 -0
  181. package/src/utils/test/crdt-utils.ts +387 -0
  182. package/src/utils/test/crdt.ts +291 -54
@@ -9,10 +9,12 @@ import {
9
9
  LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS
10
10
  } from "./config.mjs";
11
11
  import { STORE_NAME as coreStore } from "../name.mjs";
12
+ import { htmlIndexToRichTextOffset } from "../utils/crdt-utils.mjs";
12
13
  import {
13
14
  areSelectionsStatesEqual,
14
15
  getSelectionState,
15
- SelectionType
16
+ SelectionType,
17
+ SelectionDirection
16
18
  } from "../utils/crdt-user-selections.mjs";
17
19
  var PostEditorAwareness = class extends BaseAwarenessState {
18
20
  constructor(doc, kind, name, postId) {
@@ -41,12 +43,19 @@ var PostEditorAwareness = class extends BaseAwarenessState {
41
43
  let selectionStart = getSelectionStart();
42
44
  let selectionEnd = getSelectionEnd();
43
45
  let localCursorTimeout = null;
46
+ let selectionBeforeDebounce = null;
44
47
  subscribe(() => {
45
48
  const newSelectionStart = getSelectionStart();
46
49
  const newSelectionEnd = getSelectionEnd();
47
50
  if (newSelectionStart === selectionStart && newSelectionEnd === selectionEnd) {
48
51
  return;
49
52
  }
53
+ if (!selectionBeforeDebounce) {
54
+ selectionBeforeDebounce = {
55
+ start: selectionStart,
56
+ end: selectionEnd
57
+ };
58
+ }
50
59
  selectionStart = newSelectionStart;
51
60
  selectionEnd = newSelectionEnd;
52
61
  const initialPosition = getSelectedBlocksInitialCaretPosition();
@@ -59,10 +68,21 @@ var PostEditorAwareness = class extends BaseAwarenessState {
59
68
  clearTimeout(localCursorTimeout);
60
69
  }
61
70
  localCursorTimeout = setTimeout(() => {
71
+ const selectionStateOptions = {};
72
+ if (selectionBeforeDebounce) {
73
+ selectionStateOptions.selectionDirection = detectSelectionDirection(
74
+ selectionBeforeDebounce.start,
75
+ selectionBeforeDebounce.end,
76
+ selectionStart,
77
+ selectionEnd
78
+ );
79
+ selectionBeforeDebounce = null;
80
+ }
62
81
  const selectionState = getSelectionState(
63
82
  selectionStart,
64
83
  selectionEnd,
65
- this.doc
84
+ this.doc,
85
+ selectionStateOptions
66
86
  );
67
87
  this.setThrottledLocalStateField(
68
88
  "editorState",
@@ -105,6 +125,9 @@ var PostEditorAwareness = class extends BaseAwarenessState {
105
125
  if (!state1 || !state2) {
106
126
  return state1 === state2;
107
127
  }
128
+ if (!state1.selection || !state2.selection) {
129
+ return state1.selection === state2.selection;
130
+ }
108
131
  return areSelectionsStatesEqual(state1.selection, state2.selection);
109
132
  }
110
133
  /**
@@ -121,11 +144,11 @@ var PostEditorAwareness = class extends BaseAwarenessState {
121
144
  * clientIds (e.g. in "Show Template" mode where blocks are cloned).
122
145
  *
123
146
  * @param selection - The selection state.
124
- * @return The text index and block client ID, or nulls if not resolvable.
147
+ * @return The rich-text offset and block client ID, or nulls if not resolvable.
125
148
  */
126
149
  convertSelectionStateToAbsolute(selection) {
127
150
  if (selection.type === SelectionType.None) {
128
- return { textIndex: null, localClientId: null };
151
+ return { richTextOffset: null, localClientId: null };
129
152
  }
130
153
  if (selection.type === SelectionType.WholeBlock) {
131
154
  const absolutePos = Y.createAbsolutePositionFromRelativePosition(
@@ -141,7 +164,7 @@ var PostEditorAwareness = class extends BaseAwarenessState {
141
164
  localClientId2 = path2 ? resolveBlockClientIdByPath(path2) : null;
142
165
  }
143
166
  }
144
- return { textIndex: null, localClientId: localClientId2 };
167
+ return { richTextOffset: null, localClientId: localClientId2 };
145
168
  }
146
169
  const cursorPos = "cursorPosition" in selection ? selection.cursorPosition : selection.cursorStartPosition;
147
170
  const absolutePosition = Y.createAbsolutePositionFromRelativePosition(
@@ -149,12 +172,18 @@ var PostEditorAwareness = class extends BaseAwarenessState {
149
172
  this.doc
150
173
  );
151
174
  if (!absolutePosition) {
152
- return { textIndex: null, localClientId: null };
175
+ return { richTextOffset: null, localClientId: null };
153
176
  }
154
177
  const yType = absolutePosition.type.parent?.parent;
155
178
  const path = yType instanceof Y.Map ? getBlockPathInYdoc(yType) : null;
156
179
  const localClientId = path ? resolveBlockClientIdByPath(path) : null;
157
- return { textIndex: absolutePosition.index, localClientId };
180
+ return {
181
+ richTextOffset: htmlIndexToRichTextOffset(
182
+ absolutePosition.type.toString(),
183
+ absolutePosition.index
184
+ ),
185
+ localClientId
186
+ };
158
187
  }
159
188
  /**
160
189
  * Type guard to check if a struct is a Y.Item (not Y.GC)
@@ -217,6 +246,17 @@ var PostEditorAwareness = class extends BaseAwarenessState {
217
246
  };
218
247
  }
219
248
  };
249
+ function detectSelectionDirection(prevStart, prevEnd, newStart, newEnd) {
250
+ const startMoved = !areBlockSelectionsEqual(prevStart, newStart);
251
+ const endMoved = !areBlockSelectionsEqual(prevEnd, newEnd);
252
+ if (startMoved && !endMoved) {
253
+ return SelectionDirection.Backward;
254
+ }
255
+ return SelectionDirection.Forward;
256
+ }
257
+ function areBlockSelectionsEqual(a, b) {
258
+ return a.clientId === b.clientId && a.attributeKey === b.attributeKey && a.offset === b.offset;
259
+ }
220
260
  export {
221
261
  PostEditorAwareness
222
262
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/awareness/post-editor-awareness.ts"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { dispatch, select, subscribe } from '@wordpress/data';\nimport { Y } from '@wordpress/sync';\n// @ts-ignore No exported types for block editor store selectors.\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { BaseAwarenessState, baseEqualityFieldChecks } from './base-awareness';\nimport { getBlockPathInYdoc, resolveBlockClientIdByPath } from './block-lookup';\nimport {\n\tAWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS,\n\tLOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS,\n} from './config';\nimport { STORE_NAME as coreStore } from '../name';\nimport {\n\tareSelectionsStatesEqual,\n\tgetSelectionState,\n\tSelectionType,\n} from '../utils/crdt-user-selections';\n\nimport type { SelectionState, WPBlockSelection } from '../types';\nimport type { YBlocks } from '../utils/crdt-blocks';\nimport type {\n\tDebugCollaboratorData,\n\tEditorState,\n\tPostEditorState,\n\tSerializableYItem,\n\tYDocDebugData,\n} from './types';\n\nexport class PostEditorAwareness extends BaseAwarenessState< PostEditorState > {\n\tprotected equalityFieldChecks = {\n\t\t...baseEqualityFieldChecks,\n\t\teditorState: this.areEditorStatesEqual,\n\t};\n\n\tpublic constructor(\n\t\tdoc: Y.Doc,\n\t\tprivate kind: string,\n\t\tprivate name: string,\n\t\tprivate postId: number\n\t) {\n\t\tsuper( doc );\n\t}\n\n\tprotected onSetUp(): void {\n\t\tsuper.onSetUp();\n\n\t\tthis.subscribeToCollaboratorSelectionChanges();\n\t}\n\n\t/**\n\t * Subscribe to collaborator selection changes and update the selection state.\n\t */\n\tprivate subscribeToCollaboratorSelectionChanges(): void {\n\t\tconst {\n\t\t\tgetSelectionStart,\n\t\t\tgetSelectionEnd,\n\t\t\tgetSelectedBlocksInitialCaretPosition,\n\t\t} = select( blockEditorStore );\n\n\t\t// Keep track of the current selection in the outer scope so we can compare\n\t\t// in the subscription.\n\t\tlet selectionStart = getSelectionStart();\n\t\tlet selectionEnd = getSelectionEnd();\n\t\tlet localCursorTimeout: NodeJS.Timeout | null = null;\n\n\t\tsubscribe( () => {\n\t\t\tconst newSelectionStart = getSelectionStart();\n\t\t\tconst newSelectionEnd = getSelectionEnd();\n\n\t\t\tif (\n\t\t\t\tnewSelectionStart === selectionStart &&\n\t\t\t\tnewSelectionEnd === selectionEnd\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tselectionStart = newSelectionStart;\n\t\t\tselectionEnd = newSelectionEnd;\n\n\t\t\t// Typically selection position is only persisted after typing in a block, which\n\t\t\t// can cause selection position to be reset by other users making block updates.\n\t\t\t// Ensure we update the controlled selection right away, persisting our cursor position locally.\n\t\t\tconst initialPosition = getSelectedBlocksInitialCaretPosition();\n\t\t\tvoid this.updateSelectionInEntityRecord(\n\t\t\t\tselectionStart,\n\t\t\t\tselectionEnd,\n\t\t\t\tinitialPosition\n\t\t\t);\n\n\t\t\t// We receive two selection changes in quick succession\n\t\t\t// from local selection events:\n\t\t\t// { clientId: \"123...\", attributeKey: \"content\", offset: undefined }\n\t\t\t// { clientId: \"123...\", attributeKey: \"content\", offset: 554 }\n\t\t\t// Add a short debounce to avoid sending the first selection change.\n\t\t\tif ( localCursorTimeout ) {\n\t\t\t\tclearTimeout( localCursorTimeout );\n\t\t\t}\n\n\t\t\tlocalCursorTimeout = setTimeout( () => {\n\t\t\t\tconst selectionState = getSelectionState(\n\t\t\t\t\tselectionStart,\n\t\t\t\t\tselectionEnd,\n\t\t\t\t\tthis.doc\n\t\t\t\t);\n\n\t\t\t\tthis.setThrottledLocalStateField(\n\t\t\t\t\t'editorState',\n\t\t\t\t\t{ selection: selectionState },\n\t\t\t\t\tAWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS\n\t\t\t\t);\n\t\t\t}, LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS );\n\t\t} );\n\t}\n\n\t/**\n\t * Update the entity record with the current collaborator's selection.\n\t *\n\t * @param selectionStart - The start position of the selection.\n\t * @param selectionEnd - The end position of the selection.\n\t * @param initialPosition - The initial position of the selection.\n\t */\n\tprivate async updateSelectionInEntityRecord(\n\t\tselectionStart: WPBlockSelection,\n\t\tselectionEnd: WPBlockSelection,\n\t\tinitialPosition: number | null\n\t): Promise< void > {\n\t\t// Send an entityRecord `selection` update if we have a selection.\n\t\t//\n\t\t// Normally WordPress updates the `selection` property of the post when changes are made to blocks.\n\t\t// In a multi-user setup, block changes can occur from other users. When an entity is updated from another\n\t\t// user's changes, useBlockSync() in Gutenberg will reset the user's selection to the last saved selection.\n\t\t//\n\t\t// Manually adding an edit for each movement ensures that other user's changes to the document will\n\t\t// not cause the local user's selection to reset to the last local change location.\n\t\tconst edits = {\n\t\t\tselection: { selectionStart, selectionEnd, initialPosition },\n\t\t};\n\n\t\tconst options = {\n\t\t\tundoIgnore: true,\n\t\t};\n\n\t\t// @ts-ignore Types are not provided when using store name instead of store instance.\n\t\tdispatch( coreStore ).editEntityRecord(\n\t\t\tthis.kind,\n\t\t\tthis.name,\n\t\t\tthis.postId,\n\t\t\tedits,\n\t\t\toptions\n\t\t);\n\t}\n\n\t/**\n\t * Check if two editor states are equal.\n\t *\n\t * @param state1 - The first editor state.\n\t * @param state2 - The second editor state.\n\t * @return True if the editor states are equal, false otherwise.\n\t */\n\tprivate areEditorStatesEqual(\n\t\tstate1?: EditorState,\n\t\tstate2?: EditorState\n\t): boolean {\n\t\tif ( ! state1 || ! state2 ) {\n\t\t\treturn state1 === state2;\n\t\t}\n\n\t\treturn areSelectionsStatesEqual( state1.selection, state2.selection );\n\t}\n\n\t/**\n\t * Resolve a selection state to a text index and block client ID.\n\t *\n\t * For text-based selections, navigates up from the resolved Y.Text via\n\t * AbstractType.parent to find the containing block, then resolves the\n\t * local clientId via the block's tree path.\n\t * For WholeBlock selections, resolves the block's relative position and\n\t * then finds the local clientId via tree path.\n\t *\n\t * Tree-path resolution is used instead of reading the clientId directly\n\t * from the Yjs block because the local block-editor store may use different\n\t * clientIds (e.g. in \"Show Template\" mode where blocks are cloned).\n\t *\n\t * @param selection - The selection state.\n\t * @return The text index and block client ID, or nulls if not resolvable.\n\t */\n\tpublic convertSelectionStateToAbsolute( selection: SelectionState ): {\n\t\ttextIndex: number | null;\n\t\tlocalClientId: string | null;\n\t} {\n\t\tif ( selection.type === SelectionType.None ) {\n\t\t\treturn { textIndex: null, localClientId: null };\n\t\t}\n\n\t\tif ( selection.type === SelectionType.WholeBlock ) {\n\t\t\tconst absolutePos = Y.createAbsolutePositionFromRelativePosition(\n\t\t\t\tselection.blockPosition,\n\t\t\t\tthis.doc\n\t\t\t);\n\n\t\t\tlet localClientId: string | null = null;\n\n\t\t\tif ( absolutePos && absolutePos.type instanceof Y.Array ) {\n\t\t\t\tconst parentArray = absolutePos.type as YBlocks;\n\t\t\t\tconst block = parentArray.get( absolutePos.index );\n\n\t\t\t\tif ( block instanceof Y.Map ) {\n\t\t\t\t\tconst path = getBlockPathInYdoc( block );\n\t\t\t\t\tlocalClientId = path\n\t\t\t\t\t\t? resolveBlockClientIdByPath( path )\n\t\t\t\t\t\t: null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { textIndex: null, localClientId };\n\t\t}\n\n\t\t// Text-based selections: resolve cursor position and navigate up.\n\t\tconst cursorPos =\n\t\t\t'cursorPosition' in selection\n\t\t\t\t? selection.cursorPosition\n\t\t\t\t: selection.cursorStartPosition;\n\n\t\tconst absolutePosition = Y.createAbsolutePositionFromRelativePosition(\n\t\t\tcursorPos.relativePosition,\n\t\t\tthis.doc\n\t\t);\n\n\t\tif ( ! absolutePosition ) {\n\t\t\treturn { textIndex: null, localClientId: null };\n\t\t}\n\n\t\t// Navigate up: Y.Text -> attributes Y.Map -> block Y.Map\n\t\tconst yType = absolutePosition.type.parent?.parent;\n\t\tconst path =\n\t\t\tyType instanceof Y.Map ? getBlockPathInYdoc( yType ) : null;\n\t\tconst localClientId = path ? resolveBlockClientIdByPath( path ) : null;\n\n\t\treturn { textIndex: absolutePosition.index, localClientId };\n\t}\n\n\t/**\n\t * Type guard to check if a struct is a Y.Item (not Y.GC)\n\t * @param struct - The struct to check.\n\t * @return True if the struct is a Y.Item, false otherwise.\n\t */\n\tprivate isYItem( struct: Y.Item | Y.GC ): struct is Y.Item {\n\t\treturn 'content' in struct;\n\t}\n\n\t/**\n\t * Get data for debugging, using the awareness state.\n\t *\n\t * @return {YDocDebugData} The debug data.\n\t */\n\tpublic getDebugData(): YDocDebugData {\n\t\tconst ydoc = this.doc;\n\n\t\t// Manually extract doc data to avoid deprecated toJSON method\n\t\tconst docData: Record< string, unknown > = Object.fromEntries(\n\t\t\tArray.from( ydoc.share, ( [ key, value ] ) => [\n\t\t\t\tkey,\n\t\t\t\tvalue.toJSON(),\n\t\t\t] )\n\t\t);\n\n\t\t// Build collaboratorMap from awareness store (all collaborators seen this session)\n\t\tconst collaboratorMapData = new Map< string, DebugCollaboratorData >(\n\t\t\tArray.from( this.getSeenStates().entries() ).map(\n\t\t\t\t( [ clientId, collaboratorState ] ) => [\n\t\t\t\t\tString( clientId ),\n\t\t\t\t\t{\n\t\t\t\t\t\tname: collaboratorState.collaboratorInfo.name,\n\t\t\t\t\t\twpUserId: collaboratorState.collaboratorInfo.id,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t)\n\t\t);\n\n\t\t// Serialize Yjs client items to avoid deep nesting\n\t\tconst serializableClientItems: Record<\n\t\t\tnumber,\n\t\t\tArray< SerializableYItem >\n\t\t> = {};\n\n\t\tydoc.store.clients.forEach( ( structs, clientId ) => {\n\t\t\t// Filter for Y.Item only (skip Y.GC garbage collection structs)\n\t\t\tconst items = structs.filter( this.isYItem );\n\n\t\t\tserializableClientItems[ clientId ] = items.map( ( item ) => {\n\t\t\t\tconst { left, right, ...rest } = item;\n\n\t\t\t\treturn {\n\t\t\t\t\t...rest,\n\t\t\t\t\tleft: left\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tid: left.id,\n\t\t\t\t\t\t\t\tlength: left.length,\n\t\t\t\t\t\t\t\torigin: left.origin,\n\t\t\t\t\t\t\t\tcontent: left.content,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: null,\n\t\t\t\t\tright: right\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tid: right.id,\n\t\t\t\t\t\t\t\tlength: right.length,\n\t\t\t\t\t\t\t\torigin: right.origin,\n\t\t\t\t\t\t\t\tcontent: right.content,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: null,\n\t\t\t\t};\n\t\t\t} );\n\t\t} );\n\n\t\treturn {\n\t\t\tdoc: docData,\n\t\t\tclients: serializableClientItems,\n\t\t\tcollaboratorMap: Object.fromEntries( collaboratorMapData ),\n\t\t};\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { dispatch, select, subscribe } from '@wordpress/data';\nimport { Y } from '@wordpress/sync';\n// @ts-ignore No exported types for block editor store selectors.\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { BaseAwarenessState, baseEqualityFieldChecks } from './base-awareness';\nimport { getBlockPathInYdoc, resolveBlockClientIdByPath } from './block-lookup';\nimport {\n\tAWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS,\n\tLOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS,\n} from './config';\nimport { STORE_NAME as coreStore } from '../name';\nimport { htmlIndexToRichTextOffset } from '../utils/crdt-utils';\nimport {\n\tareSelectionsStatesEqual,\n\tgetSelectionState,\n\tSelectionType,\n\tSelectionDirection,\n} from '../utils/crdt-user-selections';\n\nimport type { SelectionState, WPBlockSelection } from '../types';\nimport type { YBlocks } from '../utils/crdt-blocks';\nimport type {\n\tDebugCollaboratorData,\n\tEditorState,\n\tPostEditorState,\n\tSerializableYItem,\n\tYDocDebugData,\n} from './types';\n\nexport class PostEditorAwareness extends BaseAwarenessState< PostEditorState > {\n\tprotected equalityFieldChecks = {\n\t\t...baseEqualityFieldChecks,\n\t\teditorState: this.areEditorStatesEqual,\n\t};\n\n\tpublic constructor(\n\t\tdoc: Y.Doc,\n\t\tprivate kind: string,\n\t\tprivate name: string,\n\t\tprivate postId: number\n\t) {\n\t\tsuper( doc );\n\t}\n\n\tprotected onSetUp(): void {\n\t\tsuper.onSetUp();\n\n\t\tthis.subscribeToCollaboratorSelectionChanges();\n\t}\n\n\t/**\n\t * Subscribe to collaborator selection changes and update the selection state.\n\t */\n\tprivate subscribeToCollaboratorSelectionChanges(): void {\n\t\tconst {\n\t\t\tgetSelectionStart,\n\t\t\tgetSelectionEnd,\n\t\t\tgetSelectedBlocksInitialCaretPosition,\n\t\t} = select( blockEditorStore );\n\n\t\t// Keep track of the current selection in the outer scope so we can compare\n\t\t// in the subscription.\n\t\tlet selectionStart = getSelectionStart();\n\t\tlet selectionEnd = getSelectionEnd();\n\t\tlet localCursorTimeout: NodeJS.Timeout | null = null;\n\n\t\t// During rapid selection changes (e.g. undo restoring content and\n\t\t// selection), the debounce discards intermediate events. If we use the\n\t\t// last intermediate state instead of the overall change it can produce\n\t\t// the wrong direction.\n\t\t// Use selectionBeforeDebounce to capture the selection state from\n\t\t// before the debounce window so that direction is computed across the\n\t\t// full window when it fires.\n\t\tlet selectionBeforeDebounce: {\n\t\t\tstart: WPBlockSelection;\n\t\t\tend: WPBlockSelection;\n\t\t} | null = null;\n\n\t\tsubscribe( () => {\n\t\t\tconst newSelectionStart = getSelectionStart();\n\t\t\tconst newSelectionEnd = getSelectionEnd();\n\n\t\t\tif (\n\t\t\t\tnewSelectionStart === selectionStart &&\n\t\t\t\tnewSelectionEnd === selectionEnd\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// On the first change of a debounce window, snapshot the state\n\t\t\t// we're moving away from.\n\t\t\tif ( ! selectionBeforeDebounce ) {\n\t\t\t\tselectionBeforeDebounce = {\n\t\t\t\t\tstart: selectionStart,\n\t\t\t\t\tend: selectionEnd,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tselectionStart = newSelectionStart;\n\t\t\tselectionEnd = newSelectionEnd;\n\n\t\t\t// Typically selection position is only persisted after typing in a block, which\n\t\t\t// can cause selection position to be reset by other users making block updates.\n\t\t\t// Ensure we update the controlled selection right away, persisting our cursor position locally.\n\t\t\tconst initialPosition = getSelectedBlocksInitialCaretPosition();\n\t\t\tvoid this.updateSelectionInEntityRecord(\n\t\t\t\tselectionStart,\n\t\t\t\tselectionEnd,\n\t\t\t\tinitialPosition\n\t\t\t);\n\n\t\t\t// We receive two selection changes in quick succession\n\t\t\t// from local selection events:\n\t\t\t// { clientId: \"123...\", attributeKey: \"content\", offset: undefined }\n\t\t\t// { clientId: \"123...\", attributeKey: \"content\", offset: 554 }\n\t\t\t// Add a short debounce to avoid sending the first selection change.\n\t\t\tif ( localCursorTimeout ) {\n\t\t\t\tclearTimeout( localCursorTimeout );\n\t\t\t}\n\n\t\t\tlocalCursorTimeout = setTimeout( () => {\n\t\t\t\t// Compute direction across the full debounce window.\n\t\t\t\tconst selectionStateOptions: {\n\t\t\t\t\tselectionDirection?: SelectionDirection;\n\t\t\t\t} = {};\n\n\t\t\t\tif ( selectionBeforeDebounce ) {\n\t\t\t\t\tselectionStateOptions.selectionDirection =\n\t\t\t\t\t\tdetectSelectionDirection(\n\t\t\t\t\t\t\tselectionBeforeDebounce.start,\n\t\t\t\t\t\t\tselectionBeforeDebounce.end,\n\t\t\t\t\t\t\tselectionStart,\n\t\t\t\t\t\t\tselectionEnd\n\t\t\t\t\t\t);\n\n\t\t\t\t\t// Reset debounced selection state.\n\t\t\t\t\tselectionBeforeDebounce = null;\n\t\t\t\t}\n\n\t\t\t\tconst selectionState = getSelectionState(\n\t\t\t\t\tselectionStart,\n\t\t\t\t\tselectionEnd,\n\t\t\t\t\tthis.doc,\n\t\t\t\t\tselectionStateOptions\n\t\t\t\t);\n\n\t\t\t\tthis.setThrottledLocalStateField(\n\t\t\t\t\t'editorState',\n\t\t\t\t\t{ selection: selectionState },\n\t\t\t\t\tAWARENESS_CURSOR_UPDATE_THROTTLE_IN_MS\n\t\t\t\t);\n\t\t\t}, LOCAL_CURSOR_UPDATE_DEBOUNCE_IN_MS );\n\t\t} );\n\t}\n\n\t/**\n\t * Update the entity record with the current collaborator's selection.\n\t *\n\t * @param selectionStart - The start position of the selection.\n\t * @param selectionEnd - The end position of the selection.\n\t * @param initialPosition - The initial position of the selection.\n\t */\n\tprivate async updateSelectionInEntityRecord(\n\t\tselectionStart: WPBlockSelection,\n\t\tselectionEnd: WPBlockSelection,\n\t\tinitialPosition: number | null\n\t): Promise< void > {\n\t\t// Send an entityRecord `selection` update if we have a selection.\n\t\t//\n\t\t// Normally WordPress updates the `selection` property of the post when changes are made to blocks.\n\t\t// In a multi-user setup, block changes can occur from other users. When an entity is updated from another\n\t\t// user's changes, useBlockSync() in Gutenberg will reset the user's selection to the last saved selection.\n\t\t//\n\t\t// Manually adding an edit for each movement ensures that other user's changes to the document will\n\t\t// not cause the local user's selection to reset to the last local change location.\n\t\tconst edits = {\n\t\t\tselection: { selectionStart, selectionEnd, initialPosition },\n\t\t};\n\n\t\tconst options = {\n\t\t\tundoIgnore: true,\n\t\t};\n\n\t\t// @ts-ignore Types are not provided when using store name instead of store instance.\n\t\tdispatch( coreStore ).editEntityRecord(\n\t\t\tthis.kind,\n\t\t\tthis.name,\n\t\t\tthis.postId,\n\t\t\tedits,\n\t\t\toptions\n\t\t);\n\t}\n\n\t/**\n\t * Check if two editor states are equal.\n\t *\n\t * @param state1 - The first editor state.\n\t * @param state2 - The second editor state.\n\t * @return True if the editor states are equal, false otherwise.\n\t */\n\tprivate areEditorStatesEqual(\n\t\tstate1?: EditorState,\n\t\tstate2?: EditorState\n\t): boolean {\n\t\tif ( ! state1 || ! state2 ) {\n\t\t\treturn state1 === state2;\n\t\t}\n\n\t\tif ( ! state1.selection || ! state2.selection ) {\n\t\t\treturn state1.selection === state2.selection;\n\t\t}\n\n\t\treturn areSelectionsStatesEqual( state1.selection, state2.selection );\n\t}\n\n\t/**\n\t * Resolve a selection state to a text index and block client ID.\n\t *\n\t * For text-based selections, navigates up from the resolved Y.Text via\n\t * AbstractType.parent to find the containing block, then resolves the\n\t * local clientId via the block's tree path.\n\t * For WholeBlock selections, resolves the block's relative position and\n\t * then finds the local clientId via tree path.\n\t *\n\t * Tree-path resolution is used instead of reading the clientId directly\n\t * from the Yjs block because the local block-editor store may use different\n\t * clientIds (e.g. in \"Show Template\" mode where blocks are cloned).\n\t *\n\t * @param selection - The selection state.\n\t * @return The rich-text offset and block client ID, or nulls if not resolvable.\n\t */\n\tpublic convertSelectionStateToAbsolute( selection: SelectionState ): {\n\t\trichTextOffset: number | null;\n\t\tlocalClientId: string | null;\n\t} {\n\t\tif ( selection.type === SelectionType.None ) {\n\t\t\treturn { richTextOffset: null, localClientId: null };\n\t\t}\n\n\t\tif ( selection.type === SelectionType.WholeBlock ) {\n\t\t\tconst absolutePos = Y.createAbsolutePositionFromRelativePosition(\n\t\t\t\tselection.blockPosition,\n\t\t\t\tthis.doc\n\t\t\t);\n\n\t\t\tlet localClientId: string | null = null;\n\n\t\t\tif ( absolutePos && absolutePos.type instanceof Y.Array ) {\n\t\t\t\tconst parentArray = absolutePos.type as YBlocks;\n\t\t\t\tconst block = parentArray.get( absolutePos.index );\n\n\t\t\t\tif ( block instanceof Y.Map ) {\n\t\t\t\t\tconst path = getBlockPathInYdoc( block );\n\t\t\t\t\tlocalClientId = path\n\t\t\t\t\t\t? resolveBlockClientIdByPath( path )\n\t\t\t\t\t\t: null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { richTextOffset: null, localClientId };\n\t\t}\n\n\t\t// Text-based selections: resolve cursor position and navigate up.\n\t\tconst cursorPos =\n\t\t\t'cursorPosition' in selection\n\t\t\t\t? selection.cursorPosition\n\t\t\t\t: selection.cursorStartPosition;\n\n\t\tconst absolutePosition = Y.createAbsolutePositionFromRelativePosition(\n\t\t\tcursorPos.relativePosition,\n\t\t\tthis.doc\n\t\t);\n\n\t\tif ( ! absolutePosition ) {\n\t\t\treturn { richTextOffset: null, localClientId: null };\n\t\t}\n\n\t\t// Navigate up: Y.Text -> attributes Y.Map -> block Y.Map\n\t\tconst yType = absolutePosition.type.parent?.parent;\n\t\tconst path =\n\t\t\tyType instanceof Y.Map ? getBlockPathInYdoc( yType ) : null;\n\t\tconst localClientId = path ? resolveBlockClientIdByPath( path ) : null;\n\n\t\treturn {\n\t\t\trichTextOffset: htmlIndexToRichTextOffset(\n\t\t\t\tabsolutePosition.type.toString(),\n\t\t\t\tabsolutePosition.index\n\t\t\t),\n\t\t\tlocalClientId,\n\t\t};\n\t}\n\n\t/**\n\t * Type guard to check if a struct is a Y.Item (not Y.GC)\n\t * @param struct - The struct to check.\n\t * @return True if the struct is a Y.Item, false otherwise.\n\t */\n\tprivate isYItem( struct: Y.Item | Y.GC ): struct is Y.Item {\n\t\treturn 'content' in struct;\n\t}\n\n\t/**\n\t * Get data for debugging, using the awareness state.\n\t *\n\t * @return {YDocDebugData} The debug data.\n\t */\n\tpublic getDebugData(): YDocDebugData {\n\t\tconst ydoc = this.doc;\n\n\t\t// Manually extract doc data to avoid deprecated toJSON method\n\t\tconst docData: Record< string, unknown > = Object.fromEntries(\n\t\t\tArray.from( ydoc.share, ( [ key, value ] ) => [\n\t\t\t\tkey,\n\t\t\t\tvalue.toJSON(),\n\t\t\t] )\n\t\t);\n\n\t\t// Build collaboratorMap from awareness store (all collaborators seen this session)\n\t\tconst collaboratorMapData = new Map< string, DebugCollaboratorData >(\n\t\t\tArray.from( this.getSeenStates().entries() ).map(\n\t\t\t\t( [ clientId, collaboratorState ] ) => [\n\t\t\t\t\tString( clientId ),\n\t\t\t\t\t{\n\t\t\t\t\t\tname: collaboratorState.collaboratorInfo.name,\n\t\t\t\t\t\twpUserId: collaboratorState.collaboratorInfo.id,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t)\n\t\t);\n\n\t\t// Serialize Yjs client items to avoid deep nesting\n\t\tconst serializableClientItems: Record<\n\t\t\tnumber,\n\t\t\tArray< SerializableYItem >\n\t\t> = {};\n\n\t\tydoc.store.clients.forEach( ( structs, clientId ) => {\n\t\t\t// Filter for Y.Item only (skip Y.GC garbage collection structs)\n\t\t\tconst items = structs.filter( this.isYItem );\n\n\t\t\tserializableClientItems[ clientId ] = items.map( ( item ) => {\n\t\t\t\tconst { left, right, ...rest } = item;\n\n\t\t\t\treturn {\n\t\t\t\t\t...rest,\n\t\t\t\t\tleft: left\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tid: left.id,\n\t\t\t\t\t\t\t\tlength: left.length,\n\t\t\t\t\t\t\t\torigin: left.origin,\n\t\t\t\t\t\t\t\tcontent: left.content,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: null,\n\t\t\t\t\tright: right\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tid: right.id,\n\t\t\t\t\t\t\t\tlength: right.length,\n\t\t\t\t\t\t\t\torigin: right.origin,\n\t\t\t\t\t\t\t\tcontent: right.content,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: null,\n\t\t\t\t};\n\t\t\t} );\n\t\t} );\n\n\t\treturn {\n\t\t\tdoc: docData,\n\t\t\tclients: serializableClientItems,\n\t\t\tcollaboratorMap: Object.fromEntries( collaboratorMapData ),\n\t\t};\n\t}\n}\n\n/**\n * Detect the direction of a selection change by comparing old and new edges.\n *\n * When the user extends a selection backward (e.g. Shift+Left), the\n * selectionStart edge moves while selectionEnd stays fixed, so the caret\n * is at the start. The reverse is true for forward extension.\n *\n * @param prevStart - The previous selectionStart.\n * @param prevEnd - The previous selectionEnd.\n * @param newStart - The new selectionStart.\n * @param newEnd - The new selectionEnd.\n * @return The detected direction, defaulting to Forward when indeterminate.\n */\nfunction detectSelectionDirection(\n\tprevStart: WPBlockSelection,\n\tprevEnd: WPBlockSelection,\n\tnewStart: WPBlockSelection,\n\tnewEnd: WPBlockSelection\n): SelectionDirection {\n\tconst startMoved = ! areBlockSelectionsEqual( prevStart, newStart );\n\tconst endMoved = ! areBlockSelectionsEqual( prevEnd, newEnd );\n\n\tif ( startMoved && ! endMoved ) {\n\t\treturn SelectionDirection.Backward;\n\t}\n\n\treturn SelectionDirection.Forward;\n}\n\n/**\n * Compare two WPBlockSelection objects by value.\n *\n * @param a - First selection.\n * @param b - Second selection.\n * @return True if all fields are equal.\n */\nfunction areBlockSelectionsEqual(\n\ta: WPBlockSelection,\n\tb: WPBlockSelection\n): boolean {\n\treturn (\n\t\ta.clientId === b.clientId &&\n\t\ta.attributeKey === b.attributeKey &&\n\t\ta.offset === b.offset\n\t);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["localClientId", "path"]
7
7
  }
@@ -7,6 +7,7 @@ import { PostEditorAwareness } from "./awareness/post-editor-awareness.mjs";
7
7
  import { getSyncManager } from "./sync.mjs";
8
8
  import {
9
9
  applyPostChangesToCRDTDoc,
10
+ defaultCollectionSyncConfig,
10
11
  defaultSyncConfig,
11
12
  getPostChangesFromCRDTDoc,
12
13
  POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE
@@ -127,7 +128,8 @@ var rootEntitiesConfig = [
127
128
  baseURLParams: { context: "edit" },
128
129
  plural: "comments",
129
130
  label: __("Comment"),
130
- supportsPagination: true
131
+ supportsPagination: true,
132
+ syncConfig: defaultCollectionSyncConfig
131
133
  },
132
134
  {
133
135
  name: "menu",
@@ -221,13 +223,7 @@ var rootEntitiesConfig = [
221
223
  plural: "icons",
222
224
  key: "name"
223
225
  }
224
- ].map((entity) => {
225
- const syncEnabledRootEntities = /* @__PURE__ */ new Set(["comment"]);
226
- if (syncEnabledRootEntities.has(entity.name)) {
227
- entity.syncConfig = defaultSyncConfig;
228
- }
229
- return entity;
230
- });
226
+ ];
231
227
  var deprecatedEntities = {
232
228
  root: {
233
229
  media: {
@@ -249,7 +245,7 @@ var additionalEntityConfigLoaders = [
249
245
  loadEntities: loadSiteEntity
250
246
  }
251
247
  ];
252
- var prePersistPostType = (persistedRecord, edits, name, isTemplate) => {
248
+ var prePersistPostType = async (persistedRecord, edits, name, isTemplate) => {
253
249
  const newEdits = {};
254
250
  if (!isTemplate && persistedRecord?.status === "auto-draft") {
255
251
  if (!edits.status && !newEdits.status) {
@@ -262,7 +258,7 @@ var prePersistPostType = (persistedRecord, edits, name, isTemplate) => {
262
258
  if (persistedRecord) {
263
259
  const objectType = `postType/${name}`;
264
260
  const objectId = persistedRecord.id;
265
- const serializedDoc = getSyncManager()?.createPersistedCRDTDoc(
261
+ const serializedDoc = await getSyncManager()?.createPersistedCRDTDoc(
266
262
  objectType,
267
263
  objectId
268
264
  );
@@ -276,14 +272,35 @@ var prePersistPostType = (persistedRecord, edits, name, isTemplate) => {
276
272
  return newEdits;
277
273
  };
278
274
  async function loadPostTypeEntities() {
279
- const postTypes = await apiFetch({
280
- path: "/wp/v2/types?context=view"
281
- });
275
+ const postTypesPromise = apiFetch({ path: "/wp/v2/types?context=view" });
276
+ const taxonomiesPromise = window._wpCollaborationEnabled ? apiFetch({ path: "/wp/v2/taxonomies?context=view" }) : Promise.resolve({});
277
+ const [postTypes, taxonomies] = await Promise.all([
278
+ postTypesPromise,
279
+ taxonomiesPromise
280
+ ]);
282
281
  return Object.entries(postTypes ?? {}).map(([name, postType]) => {
283
282
  const isTemplate = ["wp_template", "wp_template_part"].includes(
284
283
  name
285
284
  );
286
285
  const namespace = postType?.rest_namespace ?? "wp/v2";
286
+ const syncedProperties = /* @__PURE__ */ new Set([
287
+ "author",
288
+ "blocks",
289
+ "content",
290
+ "comment_status",
291
+ "date",
292
+ "excerpt",
293
+ "featured_media",
294
+ "format",
295
+ "meta",
296
+ "ping_status",
297
+ "slug",
298
+ "status",
299
+ "sticky",
300
+ "template",
301
+ "title",
302
+ ...postType.taxonomies?.map((taxonomy) => taxonomies?.[taxonomy]?.rest_base)?.filter(Boolean) ?? []
303
+ ]);
287
304
  const entity = {
288
305
  kind: "postType",
289
306
  baseURL: `/${namespace}/${postType.rest_base}`,
@@ -312,7 +329,7 @@ async function loadPostTypeEntities() {
312
329
  * @param {Partial< import('@wordpress/sync').ObjectData >} changes
313
330
  * @return {void}
314
331
  */
315
- applyChangesToCRDTDoc: (crdtDoc, changes) => applyPostChangesToCRDTDoc(crdtDoc, changes, postType),
332
+ applyChangesToCRDTDoc: (crdtDoc, changes) => applyPostChangesToCRDTDoc(crdtDoc, changes, syncedProperties),
316
333
  /**
317
334
  * Create the awareness instance for the entity's CRDT document.
318
335
  *
@@ -333,7 +350,11 @@ async function loadPostTypeEntities() {
333
350
  * @param {import('@wordpress/sync').ObjectData} editedRecord
334
351
  * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record
335
352
  */
336
- getChangesFromCRDTDoc: (crdtDoc, editedRecord) => getPostChangesFromCRDTDoc(crdtDoc, editedRecord, postType),
353
+ getChangesFromCRDTDoc: (crdtDoc, editedRecord) => getPostChangesFromCRDTDoc(
354
+ crdtDoc,
355
+ editedRecord,
356
+ syncedProperties
357
+ ),
337
358
  /**
338
359
  * Extract changes from a CRDT document that can be used to update the
339
360
  * local editor state.
@@ -342,7 +363,7 @@ async function loadPostTypeEntities() {
342
363
  * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record
343
364
  */
344
365
  getPersistedCRDTDoc: (record) => {
345
- return record?.meta[POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE] || null;
366
+ return record?.meta?.[POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE] || null;
346
367
  }
347
368
  };
348
369
  return entity;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/entities.js"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport { capitalCase, pascalCase } from 'change-case';\n\n/**\n * WordPress dependencies\n */\nimport apiFetch from '@wordpress/api-fetch';\nimport { __unstableSerializeAndClean, parse } from '@wordpress/blocks';\nimport { __ } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { PostEditorAwareness } from './awareness/post-editor-awareness';\nimport { getSyncManager } from './sync';\nimport {\n\tapplyPostChangesToCRDTDoc,\n\tdefaultSyncConfig,\n\tgetPostChangesFromCRDTDoc,\n\tPOST_META_KEY_FOR_CRDT_DOC_PERSISTENCE,\n} from './utils/crdt';\n\nexport const DEFAULT_ENTITY_KEY = 'id';\nconst POST_RAW_ATTRIBUTES = [ 'title', 'excerpt', 'content' ];\n\nconst blocksTransientEdits = {\n\tblocks: {\n\t\tread: ( record ) => parse( record.content?.raw ?? '' ),\n\t\twrite: ( record ) => ( {\n\t\t\tcontent: __unstableSerializeAndClean( record.blocks ),\n\t\t} ),\n\t},\n};\n\nexport const rootEntitiesConfig = [\n\t{\n\t\tlabel: __( 'Base' ),\n\t\tkind: 'root',\n\t\tkey: false,\n\t\tname: '__unstableBase',\n\t\tbaseURL: '/',\n\t\tbaseURLParams: {\n\t\t\t// Please also change the preload path when changing this.\n\t\t\t// @see lib/compat/wordpress-7.0/preload.php\n\t\t\t_fields: [\n\t\t\t\t'description',\n\t\t\t\t'gmt_offset',\n\t\t\t\t'home',\n\t\t\t\t'image_sizes',\n\t\t\t\t'image_size_threshold',\n\t\t\t\t'image_output_formats',\n\t\t\t\t'jpeg_interlaced',\n\t\t\t\t'png_interlaced',\n\t\t\t\t'gif_interlaced',\n\t\t\t\t'name',\n\t\t\t\t'site_icon',\n\t\t\t\t'site_icon_url',\n\t\t\t\t'site_logo',\n\t\t\t\t'timezone_string',\n\t\t\t\t'url',\n\t\t\t\t'page_for_posts',\n\t\t\t\t'page_on_front',\n\t\t\t\t'show_on_front',\n\t\t\t].join( ',' ),\n\t\t},\n\t\t// The entity doesn't support selecting multiple records.\n\t\t// The property is maintained for backward compatibility.\n\t\tplural: '__unstableBases',\n\t},\n\t{\n\t\tlabel: __( 'Post Type' ),\n\t\tname: 'postType',\n\t\tkind: 'root',\n\t\tkey: 'slug',\n\t\tbaseURL: '/wp/v2/types',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'postTypes',\n\t},\n\t{\n\t\tname: 'media',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/media',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'mediaItems',\n\t\tlabel: __( 'Media' ),\n\t\trawAttributes: [ 'caption', 'title', 'description' ],\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tname: 'taxonomy',\n\t\tkind: 'root',\n\t\tkey: 'slug',\n\t\tbaseURL: '/wp/v2/taxonomies',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'taxonomies',\n\t\tlabel: __( 'Taxonomy' ),\n\t},\n\t{\n\t\tname: 'sidebar',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/sidebars',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'sidebars',\n\t\ttransientEdits: { blocks: true },\n\t\tlabel: __( 'Widget areas' ),\n\t},\n\t{\n\t\tname: 'widget',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/widgets',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'widgets',\n\t\ttransientEdits: { blocks: true },\n\t\tlabel: __( 'Widgets' ),\n\t},\n\t{\n\t\tname: 'widgetType',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/widget-types',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'widgetTypes',\n\t\tlabel: __( 'Widget types' ),\n\t},\n\t{\n\t\tlabel: __( 'User' ),\n\t\tname: 'user',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/users',\n\t\tgetTitle: ( record ) => record?.name || record?.slug,\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'users',\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tname: 'comment',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/comments',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'comments',\n\t\tlabel: __( 'Comment' ),\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tname: 'menu',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/menus',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'menus',\n\t\tlabel: __( 'Menu' ),\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tname: 'menuItem',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/menu-items',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'menuItems',\n\t\tlabel: __( 'Menu Item' ),\n\t\trawAttributes: [ 'title' ],\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tname: 'menuLocation',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/menu-locations',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'menuLocations',\n\t\tlabel: __( 'Menu Location' ),\n\t\tkey: 'name',\n\t},\n\t{\n\t\tlabel: __( 'Global Styles' ),\n\t\tname: 'globalStyles',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/global-styles',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'globalStylesVariations', // Should be different from name.\n\t\tgetTitle: () => __( 'Custom Styles' ),\n\t\tgetRevisionsUrl: ( parentId, revisionId ) =>\n\t\t\t`/wp/v2/global-styles/${ parentId }/revisions${\n\t\t\t\trevisionId ? '/' + revisionId : ''\n\t\t\t}`,\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tlabel: __( 'Themes' ),\n\t\tname: 'theme',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/themes',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'themes',\n\t\tkey: 'stylesheet',\n\t},\n\t{\n\t\tlabel: __( 'Plugins' ),\n\t\tname: 'plugin',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/plugins',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'plugins',\n\t\tkey: 'plugin',\n\t},\n\t{\n\t\tlabel: __( 'Status' ),\n\t\tname: 'status',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/statuses',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'statuses',\n\t\tkey: 'slug',\n\t},\n\t{\n\t\tlabel: __( 'Registered Templates' ),\n\t\tname: 'registeredTemplate',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/registered-templates',\n\t\tkey: 'id',\n\t},\n\t{\n\t\tlabel: __( 'Font Collections' ),\n\t\tname: 'fontCollection',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/font-collections',\n\t\tbaseURLParams: { context: 'view' },\n\t\tplural: 'fontCollections',\n\t\tkey: 'slug',\n\t},\n\t{\n\t\tlabel: __( 'Icons' ),\n\t\tname: 'icon',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/icons',\n\t\tbaseURLParams: { context: 'view' },\n\t\tplural: 'icons',\n\t\tkey: 'name',\n\t},\n].map( ( entity ) => {\n\tconst syncEnabledRootEntities = new Set( [ 'comment' ] );\n\n\tif ( syncEnabledRootEntities.has( entity.name ) ) {\n\t\tentity.syncConfig = defaultSyncConfig;\n\t}\n\treturn entity;\n} );\n\nexport const deprecatedEntities = {\n\troot: {\n\t\tmedia: {\n\t\t\tsince: '6.9',\n\t\t\talternative: {\n\t\t\t\tkind: 'postType',\n\t\t\t\tname: 'attachment',\n\t\t\t},\n\t\t},\n\t},\n};\n\nexport const additionalEntityConfigLoaders = [\n\t{ kind: 'postType', loadEntities: loadPostTypeEntities },\n\t{ kind: 'taxonomy', loadEntities: loadTaxonomyEntities },\n\t{\n\t\tkind: 'root',\n\t\tname: 'site',\n\t\tplural: 'sites',\n\t\tloadEntities: loadSiteEntity,\n\t},\n];\n\n/**\n * Apply extra edits before persisting a post type.\n *\n * @param {Object} persistedRecord Already persisted Post\n * @param {Object} edits Edits.\n * @param {string} name Post type name.\n * @param {boolean} isTemplate Whether the post type is a template.\n * @return {Object} Updated edits.\n */\nexport const prePersistPostType = (\n\tpersistedRecord,\n\tedits,\n\tname,\n\tisTemplate\n) => {\n\tconst newEdits = {};\n\n\tif ( ! isTemplate && persistedRecord?.status === 'auto-draft' ) {\n\t\t// Saving an auto-draft should create a draft by default.\n\t\tif ( ! edits.status && ! newEdits.status ) {\n\t\t\tnewEdits.status = 'draft';\n\t\t}\n\n\t\t// Fix the auto-draft default title.\n\t\tif (\n\t\t\t( ! edits.title || edits.title === 'Auto Draft' ) &&\n\t\t\t! newEdits.title &&\n\t\t\t( ! persistedRecord?.title ||\n\t\t\t\tpersistedRecord?.title === 'Auto Draft' )\n\t\t) {\n\t\t\tnewEdits.title = '';\n\t\t}\n\t}\n\n\t// Add meta for persisted CRDT document.\n\tif ( persistedRecord ) {\n\t\tconst objectType = `postType/${ name }`;\n\t\tconst objectId = persistedRecord.id;\n\t\tconst serializedDoc = getSyncManager()?.createPersistedCRDTDoc(\n\t\t\tobjectType,\n\t\t\tobjectId\n\t\t);\n\n\t\tif ( serializedDoc ) {\n\t\t\tnewEdits.meta = {\n\t\t\t\t...edits.meta,\n\t\t\t\t[ POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE ]: serializedDoc,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn newEdits;\n};\n\n/**\n * Returns the list of post type entities.\n *\n * @return {Promise} Entities promise\n */\nasync function loadPostTypeEntities() {\n\tconst postTypes = await apiFetch( {\n\t\tpath: '/wp/v2/types?context=view',\n\t} );\n\treturn Object.entries( postTypes ?? {} ).map( ( [ name, postType ] ) => {\n\t\tconst isTemplate = [ 'wp_template', 'wp_template_part' ].includes(\n\t\t\tname\n\t\t);\n\t\tconst namespace = postType?.rest_namespace ?? 'wp/v2';\n\n\t\tconst entity = {\n\t\t\tkind: 'postType',\n\t\t\tbaseURL: `/${ namespace }/${ postType.rest_base }`,\n\t\t\tbaseURLParams: { context: 'edit' },\n\t\t\tname,\n\t\t\tlabel: postType.name,\n\t\t\ttransientEdits: {\n\t\t\t\t...blocksTransientEdits,\n\t\t\t\tselection: true,\n\t\t\t},\n\t\t\tmergedEdits: { meta: true },\n\t\t\trawAttributes: POST_RAW_ATTRIBUTES,\n\t\t\tgetTitle: ( record ) =>\n\t\t\t\trecord?.title?.rendered ||\n\t\t\t\trecord?.title ||\n\t\t\t\t( isTemplate\n\t\t\t\t\t? capitalCase( record.slug ?? '' )\n\t\t\t\t\t: String( record.id ) ),\n\t\t\t__unstablePrePersist: ( persistedRecord, edits ) =>\n\t\t\t\tprePersistPostType( persistedRecord, edits, name, isTemplate ),\n\t\t\t__unstable_rest_base: postType.rest_base,\n\t\t\tsupportsPagination: true,\n\t\t\tgetRevisionsUrl: ( parentId, revisionId ) =>\n\t\t\t\t`/${ namespace }/${\n\t\t\t\t\tpostType.rest_base\n\t\t\t\t}/${ parentId }/revisions${\n\t\t\t\t\trevisionId ? '/' + revisionId : ''\n\t\t\t\t}`,\n\t\t\trevisionKey:\n\t\t\t\tisTemplate && ! window?.__experimentalTemplateActivate\n\t\t\t\t\t? 'wp_id'\n\t\t\t\t\t: DEFAULT_ENTITY_KEY,\n\t\t};\n\n\t\t/**\n\t\t * @type {import('@wordpress/sync').SyncConfig}\n\t\t */\n\t\tentity.syncConfig = {\n\t\t\t/**\n\t\t\t * Apply changes from the local editor to the local CRDT document so\n\t\t\t * that those changes can be synced to other peers (via the provider).\n\t\t\t *\n\t\t\t * @param {import('@wordpress/sync').CRDTDoc} crdtDoc\n\t\t\t * @param {Partial< import('@wordpress/sync').ObjectData >} changes\n\t\t\t * @return {void}\n\t\t\t */\n\t\t\tapplyChangesToCRDTDoc: ( crdtDoc, changes ) =>\n\t\t\t\tapplyPostChangesToCRDTDoc( crdtDoc, changes, postType ),\n\n\t\t\t/**\n\t\t\t * Create the awareness instance for the entity's CRDT document.\n\t\t\t *\n\t\t\t * @param {import('@wordpress/sync').CRDTDoc} ydoc\n\t\t\t * @param {import('@wordpress/sync').ObjectID} objectId\n\t\t\t * @return {import('@wordpress/sync').Awareness} Awareness instance\n\t\t\t */\n\t\t\tcreateAwareness: ( ydoc, objectId ) => {\n\t\t\t\tconst kind = 'postType';\n\t\t\t\tconst id = parseInt( objectId, 10 );\n\t\t\t\treturn new PostEditorAwareness( ydoc, kind, name, id );\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Extract changes from a CRDT document that can be used to update the\n\t\t\t * local editor state.\n\t\t\t *\n\t\t\t * @param {import('@wordpress/sync').CRDTDoc} crdtDoc\n\t\t\t * @param {import('@wordpress/sync').ObjectData} editedRecord\n\t\t\t * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record\n\t\t\t */\n\t\t\tgetChangesFromCRDTDoc: ( crdtDoc, editedRecord ) =>\n\t\t\t\tgetPostChangesFromCRDTDoc( crdtDoc, editedRecord, postType ),\n\n\t\t\t/**\n\t\t\t * Extract changes from a CRDT document that can be used to update the\n\t\t\t * local editor state.\n\t\t\t *\n\t\t\t * @param {import('@wordpress/sync').ObjectData} record\n\t\t\t * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record\n\t\t\t */\n\t\t\tgetPersistedCRDTDoc: ( record ) => {\n\t\t\t\treturn (\n\t\t\t\t\trecord?.meta[ POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE ] ||\n\t\t\t\t\tnull\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\n\t\treturn entity;\n\t} );\n}\n\n/**\n * Returns the list of the taxonomies entities.\n *\n * @return {Promise} Entities promise\n */\nasync function loadTaxonomyEntities() {\n\tconst taxonomies = await apiFetch( {\n\t\tpath: '/wp/v2/taxonomies?context=view',\n\t} );\n\treturn Object.entries( taxonomies ?? {} ).map( ( [ name, taxonomy ] ) => {\n\t\tconst namespace = taxonomy?.rest_namespace ?? 'wp/v2';\n\t\tconst entity = {\n\t\t\tkind: 'taxonomy',\n\t\t\tbaseURL: `/${ namespace }/${ taxonomy.rest_base }`,\n\t\t\tbaseURLParams: { context: 'edit' },\n\t\t\tname,\n\t\t\tlabel: taxonomy.name,\n\t\t\tgetTitle: ( record ) => record?.name,\n\t\t\tsupportsPagination: true,\n\t\t};\n\n\t\tentity.syncConfig = defaultSyncConfig;\n\n\t\treturn entity;\n\t} );\n}\n\n/**\n * Returns the Site entity.\n *\n * @return {Promise} Entity promise\n */\nasync function loadSiteEntity() {\n\tconst entity = {\n\t\tlabel: __( 'Site' ),\n\t\tname: 'site',\n\t\tkind: 'root',\n\t\tkey: false,\n\t\tbaseURL: '/wp/v2/settings',\n\t\tmeta: {},\n\t};\n\n\tconst site = await apiFetch( {\n\t\tpath: entity.baseURL,\n\t\tmethod: 'OPTIONS',\n\t} );\n\n\tconst labels = {};\n\tObject.entries( site?.schema?.properties ?? {} ).forEach(\n\t\t( [ key, value ] ) => {\n\t\t\t// Ignore properties `title` and `type` keys.\n\t\t\tif ( typeof value === 'object' && value.title ) {\n\t\t\t\tlabels[ key ] = value.title;\n\t\t\t}\n\t\t}\n\t);\n\n\treturn [ { ...entity, meta: { labels } } ];\n}\n\n/**\n * Returns the entity's getter method name given its kind and name or plural name.\n *\n * @example\n * ```js\n * const nameSingular = getMethodName( 'root', 'theme', 'get' );\n * // nameSingular is getRootTheme\n *\n * const namePlural = getMethodName( 'root', 'themes', 'set' );\n * // namePlural is setRootThemes\n * ```\n *\n * @param {string} kind Entity kind.\n * @param {string} name Entity name or plural name.\n * @param {string} prefix Function prefix.\n *\n * @return {string} Method name\n */\nexport const getMethodName = ( kind, name, prefix = 'get' ) => {\n\tconst kindPrefix = kind === 'root' ? '' : pascalCase( kind );\n\tconst suffix = pascalCase( name );\n\treturn `${ prefix }${ kindPrefix }${ suffix }`;\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport { capitalCase, pascalCase } from 'change-case';\n\n/**\n * WordPress dependencies\n */\nimport apiFetch from '@wordpress/api-fetch';\nimport { __unstableSerializeAndClean, parse } from '@wordpress/blocks';\nimport { __ } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport { PostEditorAwareness } from './awareness/post-editor-awareness';\nimport { getSyncManager } from './sync';\nimport {\n\tapplyPostChangesToCRDTDoc,\n\tdefaultCollectionSyncConfig,\n\tdefaultSyncConfig,\n\tgetPostChangesFromCRDTDoc,\n\tPOST_META_KEY_FOR_CRDT_DOC_PERSISTENCE,\n} from './utils/crdt';\n\nexport const DEFAULT_ENTITY_KEY = 'id';\nconst POST_RAW_ATTRIBUTES = [ 'title', 'excerpt', 'content' ];\n\nconst blocksTransientEdits = {\n\tblocks: {\n\t\tread: ( record ) => parse( record.content?.raw ?? '' ),\n\t\twrite: ( record ) => ( {\n\t\t\tcontent: __unstableSerializeAndClean( record.blocks ),\n\t\t} ),\n\t},\n};\n\nexport const rootEntitiesConfig = [\n\t{\n\t\tlabel: __( 'Base' ),\n\t\tkind: 'root',\n\t\tkey: false,\n\t\tname: '__unstableBase',\n\t\tbaseURL: '/',\n\t\tbaseURLParams: {\n\t\t\t// Please also change the preload path when changing this.\n\t\t\t// @see lib/compat/wordpress-7.0/preload.php\n\t\t\t_fields: [\n\t\t\t\t'description',\n\t\t\t\t'gmt_offset',\n\t\t\t\t'home',\n\t\t\t\t'image_sizes',\n\t\t\t\t'image_size_threshold',\n\t\t\t\t'image_output_formats',\n\t\t\t\t'jpeg_interlaced',\n\t\t\t\t'png_interlaced',\n\t\t\t\t'gif_interlaced',\n\t\t\t\t'name',\n\t\t\t\t'site_icon',\n\t\t\t\t'site_icon_url',\n\t\t\t\t'site_logo',\n\t\t\t\t'timezone_string',\n\t\t\t\t'url',\n\t\t\t\t'page_for_posts',\n\t\t\t\t'page_on_front',\n\t\t\t\t'show_on_front',\n\t\t\t].join( ',' ),\n\t\t},\n\t\t// The entity doesn't support selecting multiple records.\n\t\t// The property is maintained for backward compatibility.\n\t\tplural: '__unstableBases',\n\t},\n\t{\n\t\tlabel: __( 'Post Type' ),\n\t\tname: 'postType',\n\t\tkind: 'root',\n\t\tkey: 'slug',\n\t\tbaseURL: '/wp/v2/types',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'postTypes',\n\t},\n\t{\n\t\tname: 'media',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/media',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'mediaItems',\n\t\tlabel: __( 'Media' ),\n\t\trawAttributes: [ 'caption', 'title', 'description' ],\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tname: 'taxonomy',\n\t\tkind: 'root',\n\t\tkey: 'slug',\n\t\tbaseURL: '/wp/v2/taxonomies',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'taxonomies',\n\t\tlabel: __( 'Taxonomy' ),\n\t},\n\t{\n\t\tname: 'sidebar',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/sidebars',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'sidebars',\n\t\ttransientEdits: { blocks: true },\n\t\tlabel: __( 'Widget areas' ),\n\t},\n\t{\n\t\tname: 'widget',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/widgets',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'widgets',\n\t\ttransientEdits: { blocks: true },\n\t\tlabel: __( 'Widgets' ),\n\t},\n\t{\n\t\tname: 'widgetType',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/widget-types',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'widgetTypes',\n\t\tlabel: __( 'Widget types' ),\n\t},\n\t{\n\t\tlabel: __( 'User' ),\n\t\tname: 'user',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/users',\n\t\tgetTitle: ( record ) => record?.name || record?.slug,\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'users',\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tname: 'comment',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/comments',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'comments',\n\t\tlabel: __( 'Comment' ),\n\t\tsupportsPagination: true,\n\t\tsyncConfig: defaultCollectionSyncConfig,\n\t},\n\t{\n\t\tname: 'menu',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/menus',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'menus',\n\t\tlabel: __( 'Menu' ),\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tname: 'menuItem',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/menu-items',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'menuItems',\n\t\tlabel: __( 'Menu Item' ),\n\t\trawAttributes: [ 'title' ],\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tname: 'menuLocation',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/menu-locations',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'menuLocations',\n\t\tlabel: __( 'Menu Location' ),\n\t\tkey: 'name',\n\t},\n\t{\n\t\tlabel: __( 'Global Styles' ),\n\t\tname: 'globalStyles',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/global-styles',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'globalStylesVariations', // Should be different from name.\n\t\tgetTitle: () => __( 'Custom Styles' ),\n\t\tgetRevisionsUrl: ( parentId, revisionId ) =>\n\t\t\t`/wp/v2/global-styles/${ parentId }/revisions${\n\t\t\t\trevisionId ? '/' + revisionId : ''\n\t\t\t}`,\n\t\tsupportsPagination: true,\n\t},\n\t{\n\t\tlabel: __( 'Themes' ),\n\t\tname: 'theme',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/themes',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'themes',\n\t\tkey: 'stylesheet',\n\t},\n\t{\n\t\tlabel: __( 'Plugins' ),\n\t\tname: 'plugin',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/plugins',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'plugins',\n\t\tkey: 'plugin',\n\t},\n\t{\n\t\tlabel: __( 'Status' ),\n\t\tname: 'status',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/statuses',\n\t\tbaseURLParams: { context: 'edit' },\n\t\tplural: 'statuses',\n\t\tkey: 'slug',\n\t},\n\t{\n\t\tlabel: __( 'Registered Templates' ),\n\t\tname: 'registeredTemplate',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/registered-templates',\n\t\tkey: 'id',\n\t},\n\t{\n\t\tlabel: __( 'Font Collections' ),\n\t\tname: 'fontCollection',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/font-collections',\n\t\tbaseURLParams: { context: 'view' },\n\t\tplural: 'fontCollections',\n\t\tkey: 'slug',\n\t},\n\t{\n\t\tlabel: __( 'Icons' ),\n\t\tname: 'icon',\n\t\tkind: 'root',\n\t\tbaseURL: '/wp/v2/icons',\n\t\tbaseURLParams: { context: 'view' },\n\t\tplural: 'icons',\n\t\tkey: 'name',\n\t},\n];\n\nexport const deprecatedEntities = {\n\troot: {\n\t\tmedia: {\n\t\t\tsince: '6.9',\n\t\t\talternative: {\n\t\t\t\tkind: 'postType',\n\t\t\t\tname: 'attachment',\n\t\t\t},\n\t\t},\n\t},\n};\n\nexport const additionalEntityConfigLoaders = [\n\t{ kind: 'postType', loadEntities: loadPostTypeEntities },\n\t{ kind: 'taxonomy', loadEntities: loadTaxonomyEntities },\n\t{\n\t\tkind: 'root',\n\t\tname: 'site',\n\t\tplural: 'sites',\n\t\tloadEntities: loadSiteEntity,\n\t},\n];\n\n/**\n * Apply extra edits before persisting a post type.\n *\n * @param {Object} persistedRecord Already persisted Post\n * @param {Object} edits Edits.\n * @param {string} name Post type name.\n * @param {boolean} isTemplate Whether the post type is a template.\n * @return {Promise< Object >} Updated edits.\n */\nexport const prePersistPostType = async (\n\tpersistedRecord,\n\tedits,\n\tname,\n\tisTemplate\n) => {\n\tconst newEdits = {};\n\n\tif ( ! isTemplate && persistedRecord?.status === 'auto-draft' ) {\n\t\t// Saving an auto-draft should create a draft by default.\n\t\tif ( ! edits.status && ! newEdits.status ) {\n\t\t\tnewEdits.status = 'draft';\n\t\t}\n\n\t\t// Fix the auto-draft default title.\n\t\tif (\n\t\t\t( ! edits.title || edits.title === 'Auto Draft' ) &&\n\t\t\t! newEdits.title &&\n\t\t\t( ! persistedRecord?.title ||\n\t\t\t\tpersistedRecord?.title === 'Auto Draft' )\n\t\t) {\n\t\t\tnewEdits.title = '';\n\t\t}\n\t}\n\n\t// Add meta for persisted CRDT document.\n\tif ( persistedRecord ) {\n\t\tconst objectType = `postType/${ name }`;\n\t\tconst objectId = persistedRecord.id;\n\t\tconst serializedDoc = await getSyncManager()?.createPersistedCRDTDoc(\n\t\t\tobjectType,\n\t\t\tobjectId\n\t\t);\n\n\t\tif ( serializedDoc ) {\n\t\t\tnewEdits.meta = {\n\t\t\t\t...edits.meta,\n\t\t\t\t[ POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE ]: serializedDoc,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn newEdits;\n};\n\n/**\n * Returns the list of post type entities.\n *\n * @return {Promise} Entities promise\n */\nasync function loadPostTypeEntities() {\n\tconst postTypesPromise = apiFetch( { path: '/wp/v2/types?context=view' } );\n\tconst taxonomiesPromise = window._wpCollaborationEnabled\n\t\t? apiFetch( { path: '/wp/v2/taxonomies?context=view' } )\n\t\t: Promise.resolve( {} );\n\tconst [ postTypes, taxonomies ] = await Promise.all( [\n\t\tpostTypesPromise,\n\t\ttaxonomiesPromise,\n\t] );\n\n\treturn Object.entries( postTypes ?? {} ).map( ( [ name, postType ] ) => {\n\t\tconst isTemplate = [ 'wp_template', 'wp_template_part' ].includes(\n\t\t\tname\n\t\t);\n\t\tconst namespace = postType?.rest_namespace ?? 'wp/v2';\n\n\t\tconst syncedProperties = new Set( [\n\t\t\t'author',\n\t\t\t'blocks',\n\t\t\t'content',\n\t\t\t'comment_status',\n\t\t\t'date',\n\t\t\t'excerpt',\n\t\t\t'featured_media',\n\t\t\t'format',\n\t\t\t'meta',\n\t\t\t'ping_status',\n\t\t\t'slug',\n\t\t\t'status',\n\t\t\t'sticky',\n\t\t\t'template',\n\t\t\t'title',\n\t\t\t...( postType.taxonomies\n\t\t\t\t?.map( ( taxonomy ) => taxonomies?.[ taxonomy ]?.rest_base )\n\t\t\t\t?.filter( Boolean ) ?? [] ),\n\t\t] );\n\n\t\tconst entity = {\n\t\t\tkind: 'postType',\n\t\t\tbaseURL: `/${ namespace }/${ postType.rest_base }`,\n\t\t\tbaseURLParams: { context: 'edit' },\n\t\t\tname,\n\t\t\tlabel: postType.name,\n\t\t\ttransientEdits: {\n\t\t\t\t...blocksTransientEdits,\n\t\t\t\tselection: true,\n\t\t\t},\n\t\t\tmergedEdits: { meta: true },\n\t\t\trawAttributes: POST_RAW_ATTRIBUTES,\n\t\t\tgetTitle: ( record ) =>\n\t\t\t\trecord?.title?.rendered ||\n\t\t\t\trecord?.title ||\n\t\t\t\t( isTemplate\n\t\t\t\t\t? capitalCase( record.slug ?? '' )\n\t\t\t\t\t: String( record.id ) ),\n\t\t\t__unstablePrePersist: ( persistedRecord, edits ) =>\n\t\t\t\tprePersistPostType( persistedRecord, edits, name, isTemplate ),\n\t\t\t__unstable_rest_base: postType.rest_base,\n\t\t\tsupportsPagination: true,\n\t\t\tgetRevisionsUrl: ( parentId, revisionId ) =>\n\t\t\t\t`/${ namespace }/${\n\t\t\t\t\tpostType.rest_base\n\t\t\t\t}/${ parentId }/revisions${\n\t\t\t\t\trevisionId ? '/' + revisionId : ''\n\t\t\t\t}`,\n\t\t\trevisionKey:\n\t\t\t\tisTemplate && ! window?.__experimentalTemplateActivate\n\t\t\t\t\t? 'wp_id'\n\t\t\t\t\t: DEFAULT_ENTITY_KEY,\n\t\t};\n\n\t\t/**\n\t\t * @type {import('@wordpress/sync').SyncConfig}\n\t\t */\n\t\tentity.syncConfig = {\n\t\t\t/**\n\t\t\t * Apply changes from the local editor to the local CRDT document so\n\t\t\t * that those changes can be synced to other peers (via the provider).\n\t\t\t *\n\t\t\t * @param {import('@wordpress/sync').CRDTDoc} crdtDoc\n\t\t\t * @param {Partial< import('@wordpress/sync').ObjectData >} changes\n\t\t\t * @return {void}\n\t\t\t */\n\t\t\tapplyChangesToCRDTDoc: ( crdtDoc, changes ) =>\n\t\t\t\tapplyPostChangesToCRDTDoc( crdtDoc, changes, syncedProperties ),\n\n\t\t\t/**\n\t\t\t * Create the awareness instance for the entity's CRDT document.\n\t\t\t *\n\t\t\t * @param {import('@wordpress/sync').CRDTDoc} ydoc\n\t\t\t * @param {import('@wordpress/sync').ObjectID} objectId\n\t\t\t * @return {import('@wordpress/sync').Awareness} Awareness instance\n\t\t\t */\n\t\t\tcreateAwareness: ( ydoc, objectId ) => {\n\t\t\t\tconst kind = 'postType';\n\t\t\t\tconst id = parseInt( objectId, 10 );\n\t\t\t\treturn new PostEditorAwareness( ydoc, kind, name, id );\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Extract changes from a CRDT document that can be used to update the\n\t\t\t * local editor state.\n\t\t\t *\n\t\t\t * @param {import('@wordpress/sync').CRDTDoc} crdtDoc\n\t\t\t * @param {import('@wordpress/sync').ObjectData} editedRecord\n\t\t\t * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record\n\t\t\t */\n\t\t\tgetChangesFromCRDTDoc: ( crdtDoc, editedRecord ) =>\n\t\t\t\tgetPostChangesFromCRDTDoc(\n\t\t\t\t\tcrdtDoc,\n\t\t\t\t\teditedRecord,\n\t\t\t\t\tsyncedProperties\n\t\t\t\t),\n\n\t\t\t/**\n\t\t\t * Extract changes from a CRDT document that can be used to update the\n\t\t\t * local editor state.\n\t\t\t *\n\t\t\t * @param {import('@wordpress/sync').ObjectData} record\n\t\t\t * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record\n\t\t\t */\n\t\t\tgetPersistedCRDTDoc: ( record ) => {\n\t\t\t\treturn (\n\t\t\t\t\trecord?.meta?.[ POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE ] ||\n\t\t\t\t\tnull\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\n\t\treturn entity;\n\t} );\n}\n\n/**\n * Returns the list of the taxonomies entities.\n *\n * @return {Promise} Entities promise\n */\nasync function loadTaxonomyEntities() {\n\tconst taxonomies = await apiFetch( {\n\t\tpath: '/wp/v2/taxonomies?context=view',\n\t} );\n\treturn Object.entries( taxonomies ?? {} ).map( ( [ name, taxonomy ] ) => {\n\t\tconst namespace = taxonomy?.rest_namespace ?? 'wp/v2';\n\t\tconst entity = {\n\t\t\tkind: 'taxonomy',\n\t\t\tbaseURL: `/${ namespace }/${ taxonomy.rest_base }`,\n\t\t\tbaseURLParams: { context: 'edit' },\n\t\t\tname,\n\t\t\tlabel: taxonomy.name,\n\t\t\tgetTitle: ( record ) => record?.name,\n\t\t\tsupportsPagination: true,\n\t\t};\n\n\t\tentity.syncConfig = defaultSyncConfig;\n\n\t\treturn entity;\n\t} );\n}\n\n/**\n * Returns the Site entity.\n *\n * @return {Promise} Entity promise\n */\nasync function loadSiteEntity() {\n\tconst entity = {\n\t\tlabel: __( 'Site' ),\n\t\tname: 'site',\n\t\tkind: 'root',\n\t\tkey: false,\n\t\tbaseURL: '/wp/v2/settings',\n\t\tmeta: {},\n\t};\n\n\tconst site = await apiFetch( {\n\t\tpath: entity.baseURL,\n\t\tmethod: 'OPTIONS',\n\t} );\n\n\tconst labels = {};\n\tObject.entries( site?.schema?.properties ?? {} ).forEach(\n\t\t( [ key, value ] ) => {\n\t\t\t// Ignore properties `title` and `type` keys.\n\t\t\tif ( typeof value === 'object' && value.title ) {\n\t\t\t\tlabels[ key ] = value.title;\n\t\t\t}\n\t\t}\n\t);\n\n\treturn [ { ...entity, meta: { labels } } ];\n}\n\n/**\n * Returns the entity's getter method name given its kind and name or plural name.\n *\n * @example\n * ```js\n * const nameSingular = getMethodName( 'root', 'theme', 'get' );\n * // nameSingular is getRootTheme\n *\n * const namePlural = getMethodName( 'root', 'themes', 'set' );\n * // namePlural is setRootThemes\n * ```\n *\n * @param {string} kind Entity kind.\n * @param {string} name Entity name or plural name.\n * @param {string} prefix Function prefix.\n *\n * @return {string} Method name\n */\nexport const getMethodName = ( kind, name, prefix = 'get' ) => {\n\tconst kindPrefix = kind === 'root' ? '' : pascalCase( kind );\n\tconst suffix = pascalCase( name );\n\treturn `${ prefix }${ kindPrefix }${ suffix }`;\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,17 +2,26 @@
2
2
  import { useContext, useMemo } from "@wordpress/element";
3
3
  import { EntityContext } from "./entity-context.mjs";
4
4
  import { jsx } from "react/jsx-runtime";
5
- function EntityProvider({ kind, type: name, id, children }) {
5
+ function EntityProvider({
6
+ kind,
7
+ type: name,
8
+ id,
9
+ revisionId,
10
+ children
11
+ }) {
6
12
  const parent = useContext(EntityContext);
7
13
  const childContext = useMemo(
8
14
  () => ({
9
15
  ...parent,
10
- [kind]: {
11
- ...parent?.[kind],
12
- [name]: id
13
- }
16
+ ...kind && {
17
+ [kind]: {
18
+ ...parent?.[kind],
19
+ [name]: id
20
+ }
21
+ },
22
+ ...revisionId !== void 0 && { revisionId }
14
23
  }),
15
- [parent, kind, name, id]
24
+ [parent, kind, name, id, revisionId]
16
25
  );
17
26
  return /* @__PURE__ */ jsx(EntityContext.Provider, { value: childContext, children });
18
27
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/entity-provider.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useContext, useMemo } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { EntityContext } from './entity-context';\n\n/**\n * Context provider component for providing\n * an entity for a specific entity.\n *\n * @param {Object} props The component's props.\n * @param {string} props.kind The entity kind.\n * @param {string} props.type The entity name.\n * @param {number} props.id The entity ID.\n * @param {*} props.children The children to wrap.\n *\n * @return {Object} The provided children, wrapped with\n * the entity's context provider.\n */\nexport default function EntityProvider( { kind, type: name, id, children } ) {\n\tconst parent = useContext( EntityContext );\n\tconst childContext = useMemo(\n\t\t() => ( {\n\t\t\t...parent,\n\t\t\t[ kind ]: {\n\t\t\t\t...parent?.[ kind ],\n\t\t\t\t[ name ]: id,\n\t\t\t},\n\t\t} ),\n\t\t[ parent, kind, name, id ]\n\t);\n\treturn (\n\t\t<EntityContext.Provider value={ childContext }>\n\t\t\t{ children }\n\t\t</EntityContext.Provider>\n\t);\n}\n"],
5
- "mappings": ";AAGA,SAAS,YAAY,eAAe;AAKpC,SAAS,qBAAqB;AA4B5B;AAba,SAAR,eAAiC,EAAE,MAAM,MAAM,MAAM,IAAI,SAAS,GAAI;AAC5E,QAAM,SAAS,WAAY,aAAc;AACzC,QAAM,eAAe;AAAA,IACpB,OAAQ;AAAA,MACP,GAAG;AAAA,MACH,CAAE,IAAK,GAAG;AAAA,QACT,GAAG,SAAU,IAAK;AAAA,QAClB,CAAE,IAAK,GAAG;AAAA,MACX;AAAA,IACD;AAAA,IACA,CAAE,QAAQ,MAAM,MAAM,EAAG;AAAA,EAC1B;AACA,SACC,oBAAC,cAAc,UAAd,EAAuB,OAAQ,cAC7B,UACH;AAEF;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useContext, useMemo } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { EntityContext } from './entity-context';\n\n/**\n * Context provider component for providing\n * an entity for a specific entity.\n *\n * @param {Object} props The component's props.\n * @param {string} props.kind The entity kind.\n * @param {string} props.type The entity name.\n * @param {number} props.id The entity ID.\n * @param {number} [props.revisionId] Optional revision ID. When set,\n * `useEntityProp` reads from the\n * revision record instead of the\n * current entity.\n * @param {*} props.children The children to wrap.\n *\n * @return {Object} The provided children, wrapped with\n * the entity's context provider.\n */\nexport default function EntityProvider( {\n\tkind,\n\ttype: name,\n\tid,\n\trevisionId,\n\tchildren,\n} ) {\n\tconst parent = useContext( EntityContext );\n\tconst childContext = useMemo(\n\t\t() => ( {\n\t\t\t...parent,\n\t\t\t...( kind && {\n\t\t\t\t[ kind ]: {\n\t\t\t\t\t...parent?.[ kind ],\n\t\t\t\t\t[ name ]: id,\n\t\t\t\t},\n\t\t\t} ),\n\t\t\t...( revisionId !== undefined && { revisionId } ),\n\t\t} ),\n\t\t[ parent, kind, name, id, revisionId ]\n\t);\n\treturn (\n\t\t<EntityContext.Provider value={ childContext }>\n\t\t\t{ children }\n\t\t</EntityContext.Provider>\n\t);\n}\n"],
5
+ "mappings": ";AAGA,SAAS,YAAY,eAAe;AAKpC,SAAS,qBAAqB;AAyC5B;AAtBa,SAAR,eAAiC;AAAA,EACvC;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AACD,GAAI;AACH,QAAM,SAAS,WAAY,aAAc;AACzC,QAAM,eAAe;AAAA,IACpB,OAAQ;AAAA,MACP,GAAG;AAAA,MACH,GAAK,QAAQ;AAAA,QACZ,CAAE,IAAK,GAAG;AAAA,UACT,GAAG,SAAU,IAAK;AAAA,UAClB,CAAE,IAAK,GAAG;AAAA,QACX;AAAA,MACD;AAAA,MACA,GAAK,eAAe,UAAa,EAAE,WAAW;AAAA,IAC/C;AAAA,IACA,CAAE,QAAQ,MAAM,MAAM,IAAI,UAAW;AAAA,EACtC;AACA,SACC,oBAAC,cAAc,UAAd,EAAuB,OAAQ,cAC7B,UACH;AAEF;",
6
6
  "names": []
7
7
  }
@@ -1,13 +1,41 @@
1
1
  // packages/core-data/src/hooks/use-entity-prop.js
2
- import { useCallback } from "@wordpress/element";
2
+ import { useCallback, useContext } from "@wordpress/element";
3
3
  import { useDispatch, useSelect } from "@wordpress/data";
4
4
  import { STORE_NAME } from "../name.mjs";
5
+ import { DEFAULT_ENTITY_KEY } from "../entities.mjs";
6
+ import { EntityContext } from "../entity-context.mjs";
5
7
  import useEntityId from "./use-entity-id.mjs";
6
8
  function useEntityProp(kind, name, prop, _id) {
7
9
  const providerId = useEntityId(kind, name);
8
10
  const id = _id ?? providerId;
11
+ const context = useContext(EntityContext);
12
+ const revisionId = context?.revisionId;
9
13
  const { value, fullValue } = useSelect(
10
14
  (select) => {
15
+ if (revisionId) {
16
+ const revisions = select(STORE_NAME).getRevisions(
17
+ kind,
18
+ name,
19
+ id,
20
+ {
21
+ per_page: -1,
22
+ context: "edit",
23
+ _fields: "id,date,author,meta,title.raw,excerpt.raw,content.raw"
24
+ }
25
+ );
26
+ const entityConfig = select(STORE_NAME).getEntityConfig(
27
+ kind,
28
+ name
29
+ );
30
+ const revKey = entityConfig?.revisionKey || DEFAULT_ENTITY_KEY;
31
+ const revision = revisions?.find(
32
+ (r) => r[revKey] === revisionId
33
+ );
34
+ return revision ? {
35
+ value: revision[prop]?.raw ?? revision[prop],
36
+ fullValue: revision[prop]
37
+ } : {};
38
+ }
11
39
  const { getEntityRecord, getEditedEntityRecord } = select(STORE_NAME);
12
40
  const record = getEntityRecord(kind, name, id);
13
41
  const editedRecord = getEditedEntityRecord(kind, name, id);
@@ -16,16 +44,19 @@ function useEntityProp(kind, name, prop, _id) {
16
44
  fullValue: record[prop]
17
45
  } : {};
18
46
  },
19
- [kind, name, id, prop]
47
+ [kind, name, id, prop, revisionId]
20
48
  );
21
49
  const { editEntityRecord } = useDispatch(STORE_NAME);
22
50
  const setValue = useCallback(
23
51
  (newValue) => {
52
+ if (revisionId) {
53
+ return;
54
+ }
24
55
  editEntityRecord(kind, name, id, {
25
56
  [prop]: newValue
26
57
  });
27
58
  },
28
- [editEntityRecord, kind, name, id, prop]
59
+ [editEntityRecord, kind, name, id, prop, revisionId]
29
60
  );
30
61
  return [value, setValue, fullValue];
31
62
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/hooks/use-entity-prop.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useCallback } from '@wordpress/element';\nimport { useDispatch, useSelect } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport { STORE_NAME } from '../name';\nimport useEntityId from './use-entity-id';\n\n/**\n * Hook that returns the value and a setter for the\n * specified property of the nearest provided\n * entity of the specified type.\n *\n * @param {string} kind The entity kind.\n * @param {string} name The entity name.\n * @param {string} prop The property name.\n * @param {number|string} [_id] An entity ID to use instead of the context-provided one.\n *\n * @return {[*, Function, *]} An array where the first item is the\n * property value, the second is the\n * setter and the third is the full value\n * \t\t\t\t\t\t\t object from REST API containing more\n * \t\t\t\t\t\t\t information like `raw`, `rendered` and\n * \t\t\t\t\t\t\t `protected` props.\n */\nexport default function useEntityProp( kind, name, prop, _id ) {\n\tconst providerId = useEntityId( kind, name );\n\tconst id = _id ?? providerId;\n\n\tconst { value, fullValue } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getEntityRecord, getEditedEntityRecord } =\n\t\t\t\tselect( STORE_NAME );\n\t\t\tconst record = getEntityRecord( kind, name, id ); // Trigger resolver.\n\t\t\tconst editedRecord = getEditedEntityRecord( kind, name, id );\n\t\t\treturn record && editedRecord\n\t\t\t\t? {\n\t\t\t\t\t\tvalue: editedRecord[ prop ],\n\t\t\t\t\t\tfullValue: record[ prop ],\n\t\t\t\t }\n\t\t\t\t: {};\n\t\t},\n\t\t[ kind, name, id, prop ]\n\t);\n\tconst { editEntityRecord } = useDispatch( STORE_NAME );\n\tconst setValue = useCallback(\n\t\t( newValue ) => {\n\t\t\teditEntityRecord( kind, name, id, {\n\t\t\t\t[ prop ]: newValue,\n\t\t\t} );\n\t\t},\n\t\t[ editEntityRecord, kind, name, id, prop ]\n\t);\n\n\treturn [ value, setValue, fullValue ];\n}\n"],
5
- "mappings": ";AAGA,SAAS,mBAAmB;AAC5B,SAAS,aAAa,iBAAiB;AAKvC,SAAS,kBAAkB;AAC3B,OAAO,iBAAiB;AAmBT,SAAR,cAAgC,MAAM,MAAM,MAAM,KAAM;AAC9D,QAAM,aAAa,YAAa,MAAM,IAAK;AAC3C,QAAM,KAAK,OAAO;AAElB,QAAM,EAAE,OAAO,UAAU,IAAI;AAAA,IAC5B,CAAE,WAAY;AACb,YAAM,EAAE,iBAAiB,sBAAsB,IAC9C,OAAQ,UAAW;AACpB,YAAM,SAAS,gBAAiB,MAAM,MAAM,EAAG;AAC/C,YAAM,eAAe,sBAAuB,MAAM,MAAM,EAAG;AAC3D,aAAO,UAAU,eACd;AAAA,QACA,OAAO,aAAc,IAAK;AAAA,QAC1B,WAAW,OAAQ,IAAK;AAAA,MACxB,IACA,CAAC;AAAA,IACL;AAAA,IACA,CAAE,MAAM,MAAM,IAAI,IAAK;AAAA,EACxB;AACA,QAAM,EAAE,iBAAiB,IAAI,YAAa,UAAW;AACrD,QAAM,WAAW;AAAA,IAChB,CAAE,aAAc;AACf,uBAAkB,MAAM,MAAM,IAAI;AAAA,QACjC,CAAE,IAAK,GAAG;AAAA,MACX,CAAE;AAAA,IACH;AAAA,IACA,CAAE,kBAAkB,MAAM,MAAM,IAAI,IAAK;AAAA,EAC1C;AAEA,SAAO,CAAE,OAAO,UAAU,SAAU;AACrC;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useCallback, useContext } from '@wordpress/element';\nimport { useDispatch, useSelect } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport { STORE_NAME } from '../name';\nimport { DEFAULT_ENTITY_KEY } from '../entities';\nimport { EntityContext } from '../entity-context';\nimport useEntityId from './use-entity-id';\n\n/**\n * Hook that returns the value and a setter for the\n * specified property of the nearest provided\n * entity of the specified type.\n *\n * @param {string} kind The entity kind.\n * @param {string} name The entity name.\n * @param {string} prop The property name.\n * @param {number|string} [_id] An entity ID to use instead of the context-provided one.\n *\n * @return {[*, Function, *]} An array where the first item is the\n * property value, the second is the\n * setter and the third is the full value\n * \t\t\t\t\t\t\t object from REST API containing more\n * \t\t\t\t\t\t\t information like `raw`, `rendered` and\n * \t\t\t\t\t\t\t `protected` props.\n */\nexport default function useEntityProp( kind, name, prop, _id ) {\n\tconst providerId = useEntityId( kind, name );\n\tconst id = _id ?? providerId;\n\tconst context = useContext( EntityContext );\n\tconst revisionId = context?.revisionId;\n\n\tconst { value, fullValue } = useSelect(\n\t\t( select ) => {\n\t\t\tif ( revisionId ) {\n\t\t\t\t// Use getRevisions (not getRevision) to read from the\n\t\t\t\t// already-cached collection. Using getRevision would\n\t\t\t\t// trigger a redundant single-revision API fetch that\n\t\t\t\t// can wipe the collection due to a race condition.\n\t\t\t\t// See https://github.com/WordPress/gutenberg/pull/76043.\n\t\t\t\tconst revisions = select( STORE_NAME ).getRevisions(\n\t\t\t\t\tkind,\n\t\t\t\t\tname,\n\t\t\t\t\tid,\n\t\t\t\t\t{\n\t\t\t\t\t\tper_page: -1,\n\t\t\t\t\t\tcontext: 'edit',\n\t\t\t\t\t\t_fields:\n\t\t\t\t\t\t\t'id,date,author,meta,title.raw,excerpt.raw,content.raw',\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tconst entityConfig = select( STORE_NAME ).getEntityConfig(\n\t\t\t\t\tkind,\n\t\t\t\t\tname\n\t\t\t\t);\n\t\t\t\tconst revKey = entityConfig?.revisionKey || DEFAULT_ENTITY_KEY;\n\t\t\t\tconst revision = revisions?.find(\n\t\t\t\t\t( r ) => r[ revKey ] === revisionId\n\t\t\t\t);\n\t\t\t\treturn revision\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tvalue: revision[ prop ]?.raw ?? revision[ prop ],\n\t\t\t\t\t\t\tfullValue: revision[ prop ],\n\t\t\t\t\t }\n\t\t\t\t\t: {};\n\t\t\t}\n\n\t\t\tconst { getEntityRecord, getEditedEntityRecord } =\n\t\t\t\tselect( STORE_NAME );\n\t\t\tconst record = getEntityRecord( kind, name, id ); // Trigger resolver.\n\t\t\tconst editedRecord = getEditedEntityRecord( kind, name, id );\n\t\t\treturn record && editedRecord\n\t\t\t\t? {\n\t\t\t\t\t\tvalue: editedRecord[ prop ],\n\t\t\t\t\t\tfullValue: record[ prop ],\n\t\t\t\t }\n\t\t\t\t: {};\n\t\t},\n\t\t[ kind, name, id, prop, revisionId ]\n\t);\n\tconst { editEntityRecord } = useDispatch( STORE_NAME );\n\tconst setValue = useCallback(\n\t\t( newValue ) => {\n\t\t\tif ( revisionId ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\teditEntityRecord( kind, name, id, {\n\t\t\t\t[ prop ]: newValue,\n\t\t\t} );\n\t\t},\n\t\t[ editEntityRecord, kind, name, id, prop, revisionId ]\n\t);\n\n\treturn [ value, setValue, fullValue ];\n}\n"],
5
+ "mappings": ";AAGA,SAAS,aAAa,kBAAkB;AACxC,SAAS,aAAa,iBAAiB;AAKvC,SAAS,kBAAkB;AAC3B,SAAS,0BAA0B;AACnC,SAAS,qBAAqB;AAC9B,OAAO,iBAAiB;AAmBT,SAAR,cAAgC,MAAM,MAAM,MAAM,KAAM;AAC9D,QAAM,aAAa,YAAa,MAAM,IAAK;AAC3C,QAAM,KAAK,OAAO;AAClB,QAAM,UAAU,WAAY,aAAc;AAC1C,QAAM,aAAa,SAAS;AAE5B,QAAM,EAAE,OAAO,UAAU,IAAI;AAAA,IAC5B,CAAE,WAAY;AACb,UAAK,YAAa;AAMjB,cAAM,YAAY,OAAQ,UAAW,EAAE;AAAA,UACtC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,YACC,UAAU;AAAA,YACV,SAAS;AAAA,YACT,SACC;AAAA,UACF;AAAA,QACD;AACA,cAAM,eAAe,OAAQ,UAAW,EAAE;AAAA,UACzC;AAAA,UACA;AAAA,QACD;AACA,cAAM,SAAS,cAAc,eAAe;AAC5C,cAAM,WAAW,WAAW;AAAA,UAC3B,CAAE,MAAO,EAAG,MAAO,MAAM;AAAA,QAC1B;AACA,eAAO,WACJ;AAAA,UACA,OAAO,SAAU,IAAK,GAAG,OAAO,SAAU,IAAK;AAAA,UAC/C,WAAW,SAAU,IAAK;AAAA,QAC1B,IACA,CAAC;AAAA,MACL;AAEA,YAAM,EAAE,iBAAiB,sBAAsB,IAC9C,OAAQ,UAAW;AACpB,YAAM,SAAS,gBAAiB,MAAM,MAAM,EAAG;AAC/C,YAAM,eAAe,sBAAuB,MAAM,MAAM,EAAG;AAC3D,aAAO,UAAU,eACd;AAAA,QACA,OAAO,aAAc,IAAK;AAAA,QAC1B,WAAW,OAAQ,IAAK;AAAA,MACxB,IACA,CAAC;AAAA,IACL;AAAA,IACA,CAAE,MAAM,MAAM,IAAI,MAAM,UAAW;AAAA,EACpC;AACA,QAAM,EAAE,iBAAiB,IAAI,YAAa,UAAW;AACrD,QAAM,WAAW;AAAA,IAChB,CAAE,aAAc;AACf,UAAK,YAAa;AACjB;AAAA,MACD;AACA,uBAAkB,MAAM,MAAM,IAAI;AAAA,QACjC,CAAE,IAAK,GAAG;AAAA,MACX,CAAE;AAAA,IACH;AAAA,IACA,CAAE,kBAAkB,MAAM,MAAM,IAAI,MAAM,UAAW;AAAA,EACtD;AAEA,SAAO,CAAE,OAAO,UAAU,SAAU;AACrC;",
6
6
  "names": []
7
7
  }