@wordpress/core-data 7.32.0 → 7.32.1-next.ff1cebbba.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 (383) hide show
  1. package/build/actions.js +375 -632
  2. package/build/actions.js.map +7 -1
  3. package/build/batch/create-batch.js +49 -62
  4. package/build/batch/create-batch.js.map +7 -1
  5. package/build/batch/default-processor.js +43 -39
  6. package/build/batch/default-processor.js.map +7 -1
  7. package/build/batch/index.js +38 -17
  8. package/build/batch/index.js.map +7 -1
  9. package/build/dynamic-entities.js +30 -32
  10. package/build/dynamic-entities.js.map +7 -1
  11. package/build/entities.js +298 -410
  12. package/build/entities.js.map +7 -1
  13. package/build/entity-context.js +29 -12
  14. package/build/entity-context.js.map +7 -1
  15. package/build/entity-provider.js +38 -46
  16. package/build/entity-provider.js.map +7 -1
  17. package/build/entity-types/attachment.js +16 -5
  18. package/build/entity-types/attachment.js.map +7 -1
  19. package/build/entity-types/base-entity-records.js +16 -42
  20. package/build/entity-types/base-entity-records.js.map +7 -1
  21. package/build/entity-types/base.js +16 -5
  22. package/build/entity-types/base.js.map +7 -1
  23. package/build/entity-types/comment.js +16 -5
  24. package/build/entity-types/comment.js.map +7 -1
  25. package/build/entity-types/global-styles-revision.js +16 -5
  26. package/build/entity-types/global-styles-revision.js.map +7 -1
  27. package/build/entity-types/helpers.js +16 -5
  28. package/build/entity-types/helpers.js.map +7 -1
  29. package/build/entity-types/index.js +16 -5
  30. package/build/entity-types/index.js.map +7 -1
  31. package/build/entity-types/menu-location.js +16 -5
  32. package/build/entity-types/menu-location.js.map +7 -1
  33. package/build/entity-types/nav-menu-item.js +16 -5
  34. package/build/entity-types/nav-menu-item.js.map +7 -1
  35. package/build/entity-types/nav-menu.js +16 -5
  36. package/build/entity-types/nav-menu.js.map +7 -1
  37. package/build/entity-types/page.js +16 -5
  38. package/build/entity-types/page.js.map +7 -1
  39. package/build/entity-types/plugin.js +16 -5
  40. package/build/entity-types/plugin.js.map +7 -1
  41. package/build/entity-types/post-revision.js +16 -5
  42. package/build/entity-types/post-revision.js.map +7 -1
  43. package/build/entity-types/post-status.js +16 -5
  44. package/build/entity-types/post-status.js.map +7 -1
  45. package/build/entity-types/post.js +16 -5
  46. package/build/entity-types/post.js.map +7 -1
  47. package/build/entity-types/settings.js +16 -5
  48. package/build/entity-types/settings.js.map +7 -1
  49. package/build/entity-types/sidebar.js +16 -5
  50. package/build/entity-types/sidebar.js.map +7 -1
  51. package/build/entity-types/taxonomy.js +16 -5
  52. package/build/entity-types/taxonomy.js.map +7 -1
  53. package/build/entity-types/term.js +16 -5
  54. package/build/entity-types/term.js.map +7 -1
  55. package/build/entity-types/theme.js +16 -5
  56. package/build/entity-types/theme.js.map +7 -1
  57. package/build/entity-types/type.js +16 -5
  58. package/build/entity-types/type.js.map +7 -1
  59. package/build/entity-types/user.js +16 -5
  60. package/build/entity-types/user.js.map +7 -1
  61. package/build/entity-types/widget-type.js +16 -5
  62. package/build/entity-types/widget-type.js.map +7 -1
  63. package/build/entity-types/widget.js +16 -5
  64. package/build/entity-types/widget.js.map +7 -1
  65. package/build/entity-types/wp-template-part.js +16 -5
  66. package/build/entity-types/wp-template-part.js.map +7 -1
  67. package/build/entity-types/wp-template.js +16 -5
  68. package/build/entity-types/wp-template.js.map +7 -1
  69. package/build/fetch/__experimental-fetch-link-suggestions.js +141 -154
  70. package/build/fetch/__experimental-fetch-link-suggestions.js.map +7 -1
  71. package/build/fetch/__experimental-fetch-url-data.js +47 -59
  72. package/build/fetch/__experimental-fetch-url-data.js.map +7 -1
  73. package/build/fetch/index.js +53 -32
  74. package/build/fetch/index.js.map +7 -1
  75. package/build/footnotes/get-footnotes-order.js +38 -25
  76. package/build/footnotes/get-footnotes-order.js.map +7 -1
  77. package/build/footnotes/get-rich-text-values-cached.js +26 -27
  78. package/build/footnotes/get-rich-text-values-cached.js.map +7 -1
  79. package/build/footnotes/index.js +68 -55
  80. package/build/footnotes/index.js.map +7 -1
  81. package/build/hooks/constants.js +33 -12
  82. package/build/hooks/constants.js.map +7 -1
  83. package/build/hooks/index.js +59 -68
  84. package/build/hooks/index.js.map +7 -1
  85. package/build/hooks/memoize.js +34 -12
  86. package/build/hooks/memoize.js.map +7 -1
  87. package/build/hooks/use-entity-block-editor.js +111 -119
  88. package/build/hooks/use-entity-block-editor.js.map +7 -1
  89. package/build/hooks/use-entity-id.js +25 -23
  90. package/build/hooks/use-entity-id.js.map +7 -1
  91. package/build/hooks/use-entity-prop.js +59 -60
  92. package/build/hooks/use-entity-prop.js.map +7 -1
  93. package/build/hooks/use-entity-record.js +95 -155
  94. package/build/hooks/use-entity-record.js.map +7 -1
  95. package/build/hooks/use-entity-records.js +131 -139
  96. package/build/hooks/use-entity-records.js.map +7 -1
  97. package/build/hooks/use-query-select.js +65 -84
  98. package/build/hooks/use-query-select.js.map +7 -1
  99. package/build/hooks/use-resource-permissions.js +92 -145
  100. package/build/hooks/use-resource-permissions.js.map +7 -1
  101. package/build/index.js +96 -153
  102. package/build/index.js.map +7 -1
  103. package/build/lock-unlock.js +31 -14
  104. package/build/lock-unlock.js.map +7 -1
  105. package/build/locks/actions.js +36 -19
  106. package/build/locks/actions.js.map +7 -1
  107. package/build/locks/engine.js +48 -47
  108. package/build/locks/engine.js.map +7 -1
  109. package/build/locks/reducer.js +54 -63
  110. package/build/locks/reducer.js.map +7 -1
  111. package/build/locks/selectors.js +35 -30
  112. package/build/locks/selectors.js.map +7 -1
  113. package/build/locks/utils.js +37 -16
  114. package/build/locks/utils.js.map +7 -1
  115. package/build/name.js +27 -12
  116. package/build/name.js.map +7 -1
  117. package/build/private-actions.js +67 -75
  118. package/build/private-actions.js.map +7 -1
  119. package/build/private-apis.js +33 -16
  120. package/build/private-apis.js.map +7 -1
  121. package/build/private-selectors.js +204 -184
  122. package/build/private-selectors.js.map +7 -1
  123. package/build/queried-data/actions.js +32 -41
  124. package/build/queried-data/actions.js.map +7 -1
  125. package/build/queried-data/get-query-parts.js +41 -79
  126. package/build/queried-data/get-query-parts.js.map +7 -1
  127. package/build/queried-data/index.js +39 -36
  128. package/build/queried-data/index.js.map +7 -1
  129. package/build/queried-data/reducer.js +162 -193
  130. package/build/queried-data/reducer.js.map +7 -1
  131. package/build/queried-data/selectors.js +57 -85
  132. package/build/queried-data/selectors.js.map +7 -1
  133. package/build/reducer.js +279 -404
  134. package/build/reducer.js.map +7 -1
  135. package/build/resolvers.js +553 -600
  136. package/build/resolvers.js.map +7 -1
  137. package/build/selectors.js +456 -981
  138. package/build/selectors.js.map +7 -1
  139. package/build/sync.js +34 -22
  140. package/build/sync.js.map +7 -1
  141. package/build/types.js +16 -5
  142. package/build/types.js.map +7 -1
  143. package/build/utils/conservative-map-item.js +34 -27
  144. package/build/utils/conservative-map-item.js.map +7 -1
  145. package/build/utils/crdt-blocks.js +289 -0
  146. package/build/utils/crdt-blocks.js.map +7 -0
  147. package/build/utils/crdt.js +202 -0
  148. package/build/utils/crdt.js.map +7 -0
  149. package/build/utils/forward-resolver.js +24 -16
  150. package/build/utils/forward-resolver.js.map +7 -1
  151. package/build/utils/get-nested-value.js +26 -21
  152. package/build/utils/get-nested-value.js.map +7 -1
  153. package/build/utils/get-normalized-comma-separable.js +25 -17
  154. package/build/utils/get-normalized-comma-separable.js.map +7 -1
  155. package/build/utils/if-matching-action.js +25 -19
  156. package/build/utils/if-matching-action.js.map +7 -1
  157. package/build/utils/index.js +77 -108
  158. package/build/utils/index.js.map +7 -1
  159. package/build/utils/is-numeric-id.js +22 -12
  160. package/build/utils/is-numeric-id.js.map +7 -1
  161. package/build/utils/is-raw-attribute.js +22 -13
  162. package/build/utils/is-raw-attribute.js.map +7 -1
  163. package/build/utils/log-entity-deprecation.js +37 -38
  164. package/build/utils/log-entity-deprecation.js.map +7 -1
  165. package/build/utils/on-sub-key.js +30 -24
  166. package/build/utils/on-sub-key.js.map +7 -1
  167. package/build/utils/receive-intermediate-results.js +29 -6
  168. package/build/utils/receive-intermediate-results.js.map +7 -1
  169. package/build/utils/replace-action.js +24 -17
  170. package/build/utils/replace-action.js.map +7 -1
  171. package/build/utils/set-nested-value.js +25 -30
  172. package/build/utils/set-nested-value.js.map +7 -1
  173. package/build/utils/user-permissions.js +41 -13
  174. package/build/utils/user-permissions.js.map +7 -1
  175. package/build/utils/with-weak-map-cache.js +26 -22
  176. package/build/utils/with-weak-map-cache.js.map +7 -1
  177. package/build-module/actions.js +322 -601
  178. package/build-module/actions.js.map +7 -1
  179. package/build-module/batch/create-batch.js +21 -57
  180. package/build-module/batch/create-batch.js.map +7 -1
  181. package/build-module/batch/default-processor.js +14 -33
  182. package/build-module/batch/default-processor.js.map +7 -1
  183. package/build-module/batch/index.js +7 -3
  184. package/build-module/batch/index.js.map +7 -1
  185. package/build-module/dynamic-entities.js +7 -28
  186. package/build-module/dynamic-entities.js.map +7 -1
  187. package/build-module/entities.js +263 -399
  188. package/build-module/entities.js.map +7 -1
  189. package/build-module/entity-context.js +7 -7
  190. package/build-module/entity-context.js.map +7 -1
  191. package/build-module/entity-provider.js +19 -42
  192. package/build-module/entity-provider.js.map +7 -1
  193. package/build-module/entity-types/attachment.js +1 -2
  194. package/build-module/entity-types/attachment.js.map +7 -1
  195. package/build-module/entity-types/base-entity-records.js +1 -37
  196. package/build-module/entity-types/base-entity-records.js.map +7 -1
  197. package/build-module/entity-types/base.js +1 -2
  198. package/build-module/entity-types/base.js.map +7 -1
  199. package/build-module/entity-types/comment.js +1 -2
  200. package/build-module/entity-types/comment.js.map +7 -1
  201. package/build-module/entity-types/global-styles-revision.js +1 -2
  202. package/build-module/entity-types/global-styles-revision.js.map +7 -1
  203. package/build-module/entity-types/helpers.js +1 -2
  204. package/build-module/entity-types/helpers.js.map +7 -1
  205. package/build-module/entity-types/index.js +1 -2
  206. package/build-module/entity-types/index.js.map +7 -1
  207. package/build-module/entity-types/menu-location.js +1 -2
  208. package/build-module/entity-types/menu-location.js.map +7 -1
  209. package/build-module/entity-types/nav-menu-item.js +1 -2
  210. package/build-module/entity-types/nav-menu-item.js.map +7 -1
  211. package/build-module/entity-types/nav-menu.js +1 -2
  212. package/build-module/entity-types/nav-menu.js.map +7 -1
  213. package/build-module/entity-types/page.js +1 -2
  214. package/build-module/entity-types/page.js.map +7 -1
  215. package/build-module/entity-types/plugin.js +1 -2
  216. package/build-module/entity-types/plugin.js.map +7 -1
  217. package/build-module/entity-types/post-revision.js +1 -2
  218. package/build-module/entity-types/post-revision.js.map +7 -1
  219. package/build-module/entity-types/post-status.js +1 -2
  220. package/build-module/entity-types/post-status.js.map +7 -1
  221. package/build-module/entity-types/post.js +1 -2
  222. package/build-module/entity-types/post.js.map +7 -1
  223. package/build-module/entity-types/settings.js +1 -2
  224. package/build-module/entity-types/settings.js.map +7 -1
  225. package/build-module/entity-types/sidebar.js +1 -2
  226. package/build-module/entity-types/sidebar.js.map +7 -1
  227. package/build-module/entity-types/taxonomy.js +1 -2
  228. package/build-module/entity-types/taxonomy.js.map +7 -1
  229. package/build-module/entity-types/term.js +1 -2
  230. package/build-module/entity-types/term.js.map +7 -1
  231. package/build-module/entity-types/theme.js +1 -2
  232. package/build-module/entity-types/theme.js.map +7 -1
  233. package/build-module/entity-types/type.js +1 -2
  234. package/build-module/entity-types/type.js.map +7 -1
  235. package/build-module/entity-types/user.js +1 -2
  236. package/build-module/entity-types/user.js.map +7 -1
  237. package/build-module/entity-types/widget-type.js +1 -2
  238. package/build-module/entity-types/widget-type.js.map +7 -1
  239. package/build-module/entity-types/widget.js +1 -2
  240. package/build-module/entity-types/widget.js.map +7 -1
  241. package/build-module/entity-types/wp-template-part.js +1 -2
  242. package/build-module/entity-types/wp-template-part.js.map +7 -1
  243. package/build-module/entity-types/wp-template.js +1 -2
  244. package/build-module/entity-types/wp-template.js.map +7 -1
  245. package/build-module/fetch/__experimental-fetch-link-suggestions.js +111 -149
  246. package/build-module/fetch/__experimental-fetch-link-suggestions.js.map +7 -1
  247. package/build-module/fetch/__experimental-fetch-url-data.js +20 -49
  248. package/build-module/fetch/__experimental-fetch-url-data.js.map +7 -1
  249. package/build-module/fetch/index.js +20 -15
  250. package/build-module/fetch/index.js.map +7 -1
  251. package/build-module/footnotes/get-footnotes-order.js +10 -19
  252. package/build-module/footnotes/get-footnotes-order.js.map +7 -1
  253. package/build-module/footnotes/get-rich-text-values-cached.js +8 -23
  254. package/build-module/footnotes/get-rich-text-values-cached.js.map +7 -1
  255. package/build-module/footnotes/index.js +34 -47
  256. package/build-module/footnotes/index.js.map +7 -1
  257. package/build-module/hooks/constants.js +11 -8
  258. package/build-module/hooks/constants.js.map +7 -1
  259. package/build-module/hooks/index.js +27 -15
  260. package/build-module/hooks/index.js.map +7 -1
  261. package/build-module/hooks/memoize.js +6 -8
  262. package/build-module/hooks/memoize.js.map +7 -1
  263. package/build-module/hooks/use-entity-block-editor.js +80 -110
  264. package/build-module/hooks/use-entity-block-editor.js.map +7 -1
  265. package/build-module/hooks/use-entity-id.js +7 -19
  266. package/build-module/hooks/use-entity-id.js.map +7 -1
  267. package/build-module/hooks/use-entity-prop.js +31 -55
  268. package/build-module/hooks/use-entity-prop.js.map +7 -1
  269. package/build-module/hooks/use-entity-record.js +63 -148
  270. package/build-module/hooks/use-entity-record.js.map +7 -1
  271. package/build-module/hooks/use-entity-records.js +98 -131
  272. package/build-module/hooks/use-entity-records.js.map +7 -1
  273. package/build-module/hooks/use-query-select.js +27 -71
  274. package/build-module/hooks/use-query-select.js.map +7 -1
  275. package/build-module/hooks/use-resource-permissions.js +57 -136
  276. package/build-module/hooks/use-resource-permissions.js.map +7 -1
  277. package/build-module/index.js +49 -71
  278. package/build-module/index.js.map +7 -1
  279. package/build-module/lock-unlock.js +8 -7
  280. package/build-module/lock-unlock.js.map +7 -1
  281. package/build-module/locks/actions.js +8 -13
  282. package/build-module/locks/actions.js.map +7 -1
  283. package/build-module/locks/engine.js +17 -38
  284. package/build-module/locks/engine.js.map +7 -1
  285. package/build-module/locks/reducer.js +37 -59
  286. package/build-module/locks/reducer.js.map +7 -1
  287. package/build-module/locks/selectors.js +16 -23
  288. package/build-module/locks/selectors.js.map +7 -1
  289. package/build-module/locks/utils.js +15 -12
  290. package/build-module/locks/utils.js.map +7 -1
  291. package/build-module/name.js +5 -8
  292. package/build-module/name.js.map +7 -1
  293. package/build-module/private-actions.js +35 -69
  294. package/build-module/private-actions.js.map +7 -1
  295. package/build-module/private-apis.js +8 -8
  296. package/build-module/private-apis.js.map +7 -1
  297. package/build-module/private-selectors.js +167 -174
  298. package/build-module/private-selectors.js.map +7 -1
  299. package/build-module/queried-data/actions.js +11 -38
  300. package/build-module/queried-data/actions.js.map +7 -1
  301. package/build-module/queried-data/get-query-parts.js +20 -75
  302. package/build-module/queried-data/get-query-parts.js.map +7 -1
  303. package/build-module/queried-data/index.js +7 -4
  304. package/build-module/queried-data/index.js.map +7 -1
  305. package/build-module/queried-data/reducer.js +134 -185
  306. package/build-module/queried-data/reducer.js.map +7 -1
  307. package/build-module/queried-data/selectors.js +23 -78
  308. package/build-module/queried-data/selectors.js.map +7 -1
  309. package/build-module/reducer.js +243 -393
  310. package/build-module/reducer.js.map +7 -1
  311. package/build-module/resolvers.js +478 -549
  312. package/build-module/resolvers.js.map +7 -1
  313. package/build-module/selectors.js +410 -953
  314. package/build-module/selectors.js.map +7 -1
  315. package/build-module/sync.js +14 -17
  316. package/build-module/sync.js.map +7 -1
  317. package/build-module/types.js +1 -2
  318. package/build-module/types.js.map +7 -1
  319. package/build-module/utils/conservative-map-item.js +6 -22
  320. package/build-module/utils/conservative-map-item.js.map +7 -1
  321. package/build-module/utils/crdt-blocks.js +255 -0
  322. package/build-module/utils/crdt-blocks.js.map +7 -0
  323. package/build-module/utils/crdt.js +167 -0
  324. package/build-module/utils/crdt.js.map +7 -0
  325. package/build-module/utils/forward-resolver.js +6 -12
  326. package/build-module/utils/forward-resolver.js.map +7 -1
  327. package/build-module/utils/get-nested-value.js +9 -18
  328. package/build-module/utils/get-nested-value.js.map +7 -1
  329. package/build-module/utils/get-normalized-comma-separable.js +7 -13
  330. package/build-module/utils/get-normalized-comma-separable.js.map +7 -1
  331. package/build-module/utils/if-matching-action.js +7 -15
  332. package/build-module/utils/if-matching-action.js.map +7 -1
  333. package/build-module/utils/index.js +35 -14
  334. package/build-module/utils/index.js.map +7 -1
  335. package/build-module/utils/is-numeric-id.js +5 -9
  336. package/build-module/utils/is-numeric-id.js.map +7 -1
  337. package/build-module/utils/is-raw-attribute.js +5 -10
  338. package/build-module/utils/is-raw-attribute.js.map +7 -1
  339. package/build-module/utils/log-entity-deprecation.js +8 -31
  340. package/build-module/utils/log-entity-deprecation.js.map +7 -1
  341. package/build-module/utils/on-sub-key.js +8 -19
  342. package/build-module/utils/on-sub-key.js.map +7 -1
  343. package/build-module/utils/receive-intermediate-results.js +7 -2
  344. package/build-module/utils/receive-intermediate-results.js.map +7 -1
  345. package/build-module/utils/replace-action.js +6 -13
  346. package/build-module/utils/replace-action.js.map +7 -1
  347. package/build-module/utils/set-nested-value.js +8 -27
  348. package/build-module/utils/set-nested-value.js.map +7 -1
  349. package/build-module/utils/user-permissions.js +19 -9
  350. package/build-module/utils/user-permissions.js.map +7 -1
  351. package/build-module/utils/with-weak-map-cache.js +8 -18
  352. package/build-module/utils/with-weak-map-cache.js.map +7 -1
  353. package/build-types/actions.d.ts.map +1 -1
  354. package/build-types/entities.d.ts +0 -56
  355. package/build-types/entities.d.ts.map +1 -1
  356. package/build-types/index.d.ts.map +1 -1
  357. package/build-types/private-selectors.d.ts.map +1 -1
  358. package/build-types/resolvers.d.ts +3 -0
  359. package/build-types/resolvers.d.ts.map +1 -1
  360. package/build-types/selectors.d.ts.map +1 -1
  361. package/build-types/sync.d.ts +6 -1
  362. package/build-types/sync.d.ts.map +1 -1
  363. package/build-types/types.d.ts +9 -0
  364. package/build-types/types.d.ts.map +1 -1
  365. package/build-types/utils/crdt-blocks.d.ts +30 -0
  366. package/build-types/utils/crdt-blocks.d.ts.map +1 -0
  367. package/build-types/utils/crdt.d.ts +49 -0
  368. package/build-types/utils/crdt.d.ts.map +1 -0
  369. package/package.json +26 -19
  370. package/src/actions.js +56 -74
  371. package/src/entities.js +59 -113
  372. package/src/private-selectors.ts +32 -7
  373. package/src/resolvers.js +173 -120
  374. package/src/selectors.ts +0 -13
  375. package/src/sync.ts +12 -0
  376. package/src/test/resolvers.js +183 -0
  377. package/src/types.ts +12 -0
  378. package/src/utils/crdt-blocks.ts +503 -0
  379. package/src/utils/crdt.ts +310 -0
  380. package/src/utils/test/crdt-blocks.ts +375 -0
  381. package/src/utils/test/crdt.ts +254 -0
  382. package/tsconfig.tsbuildinfo +1 -1
  383. package/src/sync.js +0 -27
package/src/entities.js CHANGED
@@ -7,12 +7,31 @@ import { capitalCase, pascalCase } from 'change-case';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import apiFetch from '@wordpress/api-fetch';
10
+ import { __unstableSerializeAndClean, parse } from '@wordpress/blocks';
10
11
  import { __ } from '@wordpress/i18n';
11
- import { RichTextData } from '@wordpress/rich-text';
12
+
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ import {
17
+ applyPostChangesToCRDTDoc,
18
+ defaultApplyChangesToCRDTDoc,
19
+ defaultGetChangesFromCRDTDoc,
20
+ getPostChangesFromCRDTDoc,
21
+ } from './utils/crdt';
12
22
 
13
23
  export const DEFAULT_ENTITY_KEY = 'id';
14
24
  const POST_RAW_ATTRIBUTES = [ 'title', 'excerpt', 'content' ];
15
25
 
26
+ const blocksTransientEdits = {
27
+ blocks: {
28
+ read: ( record ) => parse( record.content?.raw ?? '' ),
29
+ write: ( record ) => ( {
30
+ content: __unstableSerializeAndClean( record.blocks ),
31
+ } ),
32
+ },
33
+ };
34
+
16
35
  export const rootEntitiesConfig = [
17
36
  {
18
37
  label: __( 'Base' ),
@@ -40,24 +59,6 @@ export const rootEntitiesConfig = [
40
59
  // The entity doesn't support selecting multiple records.
41
60
  // The property is maintained for backward compatibility.
42
61
  plural: '__unstableBases',
43
- syncConfig: {
44
- fetch: async () => {
45
- return apiFetch( { path: '/' } );
46
- },
47
- applyChangesToDoc: ( doc, changes ) => {
48
- const document = doc.getMap( 'document' );
49
- Object.entries( changes ).forEach( ( [ key, value ] ) => {
50
- if ( document.get( key ) !== value ) {
51
- document.set( key, value );
52
- }
53
- } );
54
- },
55
- fromCRDTDoc: ( doc ) => {
56
- return doc.getMap( 'document' ).toJSON();
57
- },
58
- },
59
- syncObjectType: 'root/base',
60
- getSyncObjectId: () => 'index',
61
62
  },
62
63
  {
63
64
  label: __( 'Post Type' ),
@@ -67,26 +68,6 @@ export const rootEntitiesConfig = [
67
68
  baseURL: '/wp/v2/types',
68
69
  baseURLParams: { context: 'edit' },
69
70
  plural: 'postTypes',
70
- syncConfig: {
71
- fetch: async ( id ) => {
72
- return apiFetch( {
73
- path: `/wp/v2/types/${ id }?context=edit`,
74
- } );
75
- },
76
- applyChangesToDoc: ( doc, changes ) => {
77
- const document = doc.getMap( 'document' );
78
- Object.entries( changes ).forEach( ( [ key, value ] ) => {
79
- if ( document.get( key ) !== value ) {
80
- document.set( key, value );
81
- }
82
- } );
83
- },
84
- fromCRDTDoc: ( doc ) => {
85
- return doc.getMap( 'document' ).toJSON();
86
- },
87
- },
88
- syncObjectType: 'root/postType',
89
- getSyncObjectId: ( id ) => id,
90
71
  },
91
72
  {
92
73
  name: 'media',
@@ -276,29 +257,6 @@ export const prePersistPostType = ( persistedRecord, edits ) => {
276
257
  return newEdits;
277
258
  };
278
259
 
279
- const serialisableBlocksCache = new WeakMap();
280
-
281
- function makeBlockAttributesSerializable( attributes ) {
282
- const newAttributes = { ...attributes };
283
- for ( const [ key, value ] of Object.entries( attributes ) ) {
284
- if ( value instanceof RichTextData ) {
285
- newAttributes[ key ] = value.valueOf();
286
- }
287
- }
288
- return newAttributes;
289
- }
290
-
291
- function makeBlocksSerializable( blocks ) {
292
- return blocks.map( ( block ) => {
293
- const { innerBlocks, attributes, ...rest } = block;
294
- return {
295
- ...rest,
296
- attributes: makeBlockAttributesSerializable( attributes ),
297
- innerBlocks: makeBlocksSerializable( innerBlocks ),
298
- };
299
- } );
300
- }
301
-
302
260
  /**
303
261
  * Returns the list of post type entities.
304
262
  *
@@ -313,6 +271,41 @@ async function loadPostTypeEntities() {
313
271
  name
314
272
  );
315
273
  const namespace = postType?.rest_namespace ?? 'wp/v2';
274
+
275
+ /**
276
+ * @type {import('@wordpress/sync').SyncConfig}
277
+ */
278
+ const syncConfig = {
279
+ /**
280
+ * Apply changes from the local editor to the local CRDT document so
281
+ * that those changes can be synced to other peers (via the provider).
282
+ *
283
+ * @param {import('@wordpress/sync').CRDTDoc} crdtDoc
284
+ * @param {Partial< import('@wordpress/sync').ObjectData >} changes
285
+ * @return {void}
286
+ */
287
+ applyChangesToCRDTDoc: ( crdtDoc, changes ) =>
288
+ applyPostChangesToCRDTDoc( crdtDoc, changes, postType ),
289
+
290
+ /**
291
+ * Extract changes from a CRDT document that can be used to update the
292
+ * local editor state.
293
+ *
294
+ * @param {import('@wordpress/sync').CRDTDoc} crdtDoc
295
+ * @param {import('@wordpress/sync').ObjectData} editedRecord
296
+ * @return {Partial< import('@wordpress/sync').ObjectData >} Changes to record
297
+ */
298
+ getChangesFromCRDTDoc: ( crdtDoc, editedRecord ) =>
299
+ getPostChangesFromCRDTDoc( crdtDoc, editedRecord, postType ),
300
+
301
+ /**
302
+ * Sync features supported by the entity.
303
+ *
304
+ * @type {Record< string, boolean >}
305
+ */
306
+ supports: {},
307
+ };
308
+
316
309
  return {
317
310
  kind: 'postType',
318
311
  baseURL: `/${ namespace }/${ postType.rest_base }`,
@@ -320,7 +313,7 @@ async function loadPostTypeEntities() {
320
313
  name,
321
314
  label: postType.name,
322
315
  transientEdits: {
323
- blocks: true,
316
+ ...blocksTransientEdits,
324
317
  selection: true,
325
318
  },
326
319
  mergedEdits: { meta: true },
@@ -333,40 +326,7 @@ async function loadPostTypeEntities() {
333
326
  : String( record.id ) ),
334
327
  __unstablePrePersist: isTemplate ? undefined : prePersistPostType,
335
328
  __unstable_rest_base: postType.rest_base,
336
- syncConfig: {
337
- fetch: async ( id ) => {
338
- return apiFetch( {
339
- path: `/${ namespace }/${ postType.rest_base }/${ id }?context=edit`,
340
- } );
341
- },
342
- applyChangesToDoc: ( doc, changes ) => {
343
- const document = doc.getMap( 'document' );
344
-
345
- Object.entries( changes ).forEach( ( [ key, value ] ) => {
346
- if ( typeof value !== 'function' ) {
347
- if ( key === 'blocks' ) {
348
- if ( ! serialisableBlocksCache.has( value ) ) {
349
- serialisableBlocksCache.set(
350
- value,
351
- makeBlocksSerializable( value )
352
- );
353
- }
354
-
355
- value = serialisableBlocksCache.get( value );
356
- }
357
-
358
- if ( document.get( key ) !== value ) {
359
- document.set( key, value );
360
- }
361
- }
362
- } );
363
- },
364
- fromCRDTDoc: ( doc ) => {
365
- return doc.getMap( 'document' ).toJSON();
366
- },
367
- },
368
- syncObjectType: 'postType/' + postType.name,
369
- getSyncObjectId: ( id ) => id,
329
+ syncConfig,
370
330
  supportsPagination: true,
371
331
  getRevisionsUrl: ( parentId, revisionId ) =>
372
332
  `/${ namespace }/${
@@ -414,23 +374,9 @@ async function loadSiteEntity() {
414
374
  kind: 'root',
415
375
  baseURL: '/wp/v2/settings',
416
376
  syncConfig: {
417
- fetch: async () => {
418
- return apiFetch( { path: '/wp/v2/settings' } );
419
- },
420
- applyChangesToDoc: ( doc, changes ) => {
421
- const document = doc.getMap( 'document' );
422
- Object.entries( changes ).forEach( ( [ key, value ] ) => {
423
- if ( document.get( key ) !== value ) {
424
- document.set( key, value );
425
- }
426
- } );
427
- },
428
- fromCRDTDoc: ( doc ) => {
429
- return doc.getMap( 'document' ).toJSON();
430
- },
377
+ applyChangesToCRDTDoc: defaultApplyChangesToCRDTDoc,
378
+ getChangesFromCRDTDoc: defaultGetChangesFromCRDTDoc,
431
379
  },
432
- syncObjectType: 'root/site',
433
- getSyncObjectId: () => 'index',
434
380
  meta: {},
435
381
  };
436
382
 
@@ -240,13 +240,38 @@ export const getTemplateId = createRegistrySelector(
240
240
  // First see if the post/page has an assigned template and fetch it.
241
241
  const currentTemplateSlug = editedEntity.template;
242
242
  if ( currentTemplateSlug ) {
243
- const currentTemplate = select( STORE_NAME )
244
- .getEntityRecords( 'postType', 'wp_template', {
245
- per_page: -1,
246
- } )
247
- ?.find( ( { slug } ) => slug === currentTemplateSlug );
248
- if ( currentTemplate ) {
249
- return currentTemplate.id;
243
+ const userTemplates = select( STORE_NAME ).getEntityRecords(
244
+ 'postType',
245
+ 'wp_template',
246
+ { per_page: -1 }
247
+ );
248
+ if ( ! userTemplates ) {
249
+ return;
250
+ }
251
+ const userTemplateWithSlug = userTemplates.find(
252
+ ( { slug } ) => slug === currentTemplateSlug
253
+ );
254
+
255
+ if ( userTemplateWithSlug ) {
256
+ return userTemplateWithSlug.id;
257
+ }
258
+
259
+ const registeredTemplates = select( STORE_NAME ).getEntityRecords(
260
+ 'postType',
261
+ 'wp_registered_template',
262
+ { per_page: -1 }
263
+ );
264
+
265
+ if ( ! registeredTemplates ) {
266
+ return;
267
+ }
268
+
269
+ const registeredTemplateWithSlug = registeredTemplates.find(
270
+ ( { slug } ) => slug === currentTemplateSlug
271
+ );
272
+
273
+ if ( registeredTemplateWithSlug ) {
274
+ return registeredTemplateWithSlug.id;
250
275
  }
251
276
  }
252
277
  // If no template is assigned, use the default template.
package/src/resolvers.js CHANGED
@@ -15,6 +15,7 @@ import apiFetch from '@wordpress/api-fetch';
15
15
  */
16
16
  import { STORE_NAME } from './name';
17
17
  import { additionalEntityConfigLoaders, DEFAULT_ENTITY_KEY } from './entities';
18
+ import { syncManager } from './sync';
18
19
  import {
19
20
  forwardResolver,
20
21
  getNormalizedCommaSeparable,
@@ -23,7 +24,6 @@ import {
23
24
  ALLOWED_RESOURCE_ACTIONS,
24
25
  RECEIVE_INTERMEDIATE_RESULTS,
25
26
  } from './utils';
26
- import { getSyncProvider } from './sync';
27
27
  import { fetchBlockPatterns } from './fetch';
28
28
 
29
29
  /**
@@ -66,18 +66,6 @@ export const getCurrentUser =
66
66
  export const getEntityRecord =
67
67
  ( kind, name, key = '', query ) =>
68
68
  async ( { select, dispatch, registry, resolveSelect } ) => {
69
- // For back-compat, we allow querying for static templates through
70
- // wp_template.
71
- if (
72
- kind === 'postType' &&
73
- name === 'wp_template' &&
74
- typeof key === 'string' &&
75
- // __experimentalGetDirtyEntityRecords always calls getEntityRecord
76
- // with a string key, so we need that it's not a numeric ID.
77
- ! /^\d+$/.test( key )
78
- ) {
79
- name = 'wp_registered_template';
80
- }
81
69
  const configs = await resolveSelect.getEntitiesConfig( kind );
82
70
  const entityConfig = configs.find(
83
71
  ( config ) => config.name === name && config.kind === kind
@@ -93,127 +81,173 @@ export const getEntityRecord =
93
81
  );
94
82
 
95
83
  try {
96
- // Entity supports configs,
97
- // use the sync algorithm instead of the old fetch behavior.
84
+ if ( query !== undefined && query._fields ) {
85
+ // If requesting specific fields, items and query association to said
86
+ // records are stored by ID reference. Thus, fields must always include
87
+ // the ID.
88
+ query = {
89
+ ...query,
90
+ _fields: [
91
+ ...new Set( [
92
+ ...( getNormalizedCommaSeparable( query._fields ) ||
93
+ [] ),
94
+ entityConfig.key || DEFAULT_ENTITY_KEY,
95
+ ] ),
96
+ ].join(),
97
+ };
98
+ }
99
+
100
+ if ( query !== undefined && query._fields ) {
101
+ // The resolution cache won't consider query as reusable based on the
102
+ // fields, so it's tested here, prior to initiating the REST request,
103
+ // and without causing `getEntityRecord` resolution to occur.
104
+ const hasRecord = select.hasEntityRecord(
105
+ kind,
106
+ name,
107
+ key,
108
+ query
109
+ );
110
+ if ( hasRecord ) {
111
+ return;
112
+ }
113
+ }
114
+
115
+ let { baseURL } = entityConfig;
116
+
117
+ // For "string" IDs, use the old templates endpoint.
118
+ if (
119
+ kind === 'postType' &&
120
+ name === 'wp_template' &&
121
+ key &&
122
+ typeof key === 'string' &&
123
+ ! /^\d+$/.test( key )
124
+ ) {
125
+ baseURL =
126
+ baseURL.slice( 0, baseURL.lastIndexOf( '/' ) ) +
127
+ '/templates';
128
+ }
129
+
130
+ const path = addQueryArgs( baseURL + ( key ? '/' + key : '' ), {
131
+ ...entityConfig.baseURLParams,
132
+ ...query,
133
+ } );
134
+ const response = await apiFetch( { path, parse: false } );
135
+ const record = await response.json();
136
+ const permissions = getUserPermissionsFromAllowHeader(
137
+ response.headers?.get( 'allow' )
138
+ );
139
+
140
+ const canUserResolutionsArgs = [];
141
+ const receiveUserPermissionArgs = {};
142
+ for ( const action of ALLOWED_RESOURCE_ACTIONS ) {
143
+ receiveUserPermissionArgs[
144
+ getUserPermissionCacheKey( action, {
145
+ kind,
146
+ name,
147
+ id: key,
148
+ } )
149
+ ] = permissions[ action ];
150
+
151
+ canUserResolutionsArgs.push( [
152
+ action,
153
+ { kind, name, id: key },
154
+ ] );
155
+ }
156
+
157
+ // Entity supports syncing.
98
158
  if (
99
159
  window.__experimentalEnableSync &&
100
160
  entityConfig.syncConfig &&
101
161
  ! query
102
162
  ) {
103
163
  if ( globalThis.IS_GUTENBERG_PLUGIN ) {
104
- const objectId = entityConfig.getSyncObjectId( key );
105
-
106
- // Loads the persisted document.
107
- await getSyncProvider().bootstrap(
108
- entityConfig.syncObjectType,
109
- objectId,
110
- ( record ) => {
111
- dispatch.receiveEntityRecords(
112
- kind,
113
- name,
114
- record,
115
- query
116
- );
117
- }
118
- );
119
-
120
- // Bootstraps the edited document as well (and load from peers).
121
- await getSyncProvider().bootstrap(
122
- entityConfig.syncObjectType + '--edit',
164
+ const objectType = `${ kind }/${ name }`;
165
+ const objectId = key;
166
+
167
+ // Use the new transient "read/write" config to compute transients for
168
+ // the sync manager. Otherwise these transients are not available
169
+ // if / until the record is edited. Use a copy of the record so that
170
+ // it does not change the behavior outside this experimental flag.
171
+ const recordWithTransients = { ...record };
172
+ Object.entries( entityConfig.transientEdits ?? {} )
173
+ .filter(
174
+ ( [ propName, transientConfig ] ) =>
175
+ undefined ===
176
+ recordWithTransients[ propName ] &&
177
+ transientConfig &&
178
+ 'object' === typeof transientConfig &&
179
+ 'read' in transientConfig &&
180
+ 'function' === typeof transientConfig.read
181
+ )
182
+ .forEach( ( [ propName, transientConfig ] ) => {
183
+ recordWithTransients[ propName ] =
184
+ transientConfig.read( recordWithTransients );
185
+ } );
186
+
187
+ // Load the entity record for syncing.
188
+ await syncManager.load(
189
+ entityConfig.syncConfig,
190
+ objectType,
123
191
  objectId,
124
- ( record ) => {
125
- dispatch( {
126
- type: 'EDIT_ENTITY_RECORD',
127
- kind,
128
- name,
129
- recordId: key,
130
- edits: record,
131
- meta: {
132
- undo: undefined,
133
- },
134
- } );
192
+ recordWithTransients,
193
+ {
194
+ // Handle edits sourced from the sync manager.
195
+ editRecord: ( edits ) => {
196
+ if ( ! Object.keys( edits ).length ) {
197
+ return;
198
+ }
199
+
200
+ dispatch( {
201
+ type: 'EDIT_ENTITY_RECORD',
202
+ kind,
203
+ name,
204
+ recordId: key,
205
+ edits,
206
+ meta: {
207
+ undo: undefined,
208
+ },
209
+ } );
210
+ },
211
+ // Get the current entity record (with edits)
212
+ getEditedRecord: async () =>
213
+ await resolveSelect.getEditedEntityRecord(
214
+ kind,
215
+ name,
216
+ key
217
+ ),
135
218
  }
136
219
  );
137
220
  }
138
- } else {
139
- if ( query !== undefined && query._fields ) {
140
- // If requesting specific fields, items and query association to said
141
- // records are stored by ID reference. Thus, fields must always include
142
- // the ID.
143
- query = {
144
- ...query,
145
- _fields: [
146
- ...new Set( [
147
- ...( getNormalizedCommaSeparable(
148
- query._fields
149
- ) || [] ),
150
- entityConfig.key || DEFAULT_ENTITY_KEY,
151
- ] ),
152
- ].join(),
153
- };
154
- }
155
-
156
- if ( query !== undefined && query._fields ) {
157
- // The resolution cache won't consider query as reusable based on the
158
- // fields, so it's tested here, prior to initiating the REST request,
159
- // and without causing `getEntityRecord` resolution to occur.
160
- const hasRecord = select.hasEntityRecord(
161
- kind,
162
- name,
163
- key,
164
- query
165
- );
166
- if ( hasRecord ) {
167
- return;
168
- }
169
- }
170
-
171
- const path = addQueryArgs(
172
- entityConfig.baseURL + ( key ? '/' + key : '' ),
173
- {
174
- ...entityConfig.baseURLParams,
175
- ...query,
176
- }
177
- );
178
- const response = await apiFetch( { path, parse: false } );
179
- const record = await response.json();
180
- const permissions = getUserPermissionsFromAllowHeader(
181
- response.headers?.get( 'allow' )
182
- );
183
-
184
- const canUserResolutionsArgs = [];
185
- const receiveUserPermissionArgs = {};
186
- for ( const action of ALLOWED_RESOURCE_ACTIONS ) {
187
- receiveUserPermissionArgs[
188
- getUserPermissionCacheKey( action, {
189
- kind,
190
- name,
191
- id: key,
192
- } )
193
- ] = permissions[ action ];
194
-
195
- canUserResolutionsArgs.push( [
196
- action,
197
- { kind, name, id: key },
198
- ] );
199
- }
200
-
201
- registry.batch( () => {
202
- dispatch.receiveEntityRecords( kind, name, record, query );
203
- dispatch.receiveUserPermissions(
204
- receiveUserPermissionArgs
205
- );
206
- dispatch.finishResolutions(
207
- 'canUser',
208
- canUserResolutionsArgs
209
- );
210
- } );
211
221
  }
222
+
223
+ registry.batch( () => {
224
+ dispatch.receiveEntityRecords( kind, name, record, query );
225
+ dispatch.receiveUserPermissions( receiveUserPermissionArgs );
226
+ dispatch.finishResolutions( 'canUser', canUserResolutionsArgs );
227
+ } );
212
228
  } finally {
213
229
  dispatch.__unstableReleaseStoreLock( lock );
214
230
  }
215
231
  };
216
232
 
233
+ // Whenever a template is saved, the active templates might be updated, so
234
+ // invalidate the site settings when a template is updated or deleted.
235
+ getEntityRecord.shouldInvalidate = ( action, kind, name ) => {
236
+ return (
237
+ kind === 'root' &&
238
+ name === 'site' &&
239
+ ( ( action.type === 'RECEIVE_ITEMS' &&
240
+ // Making sure persistedEdits is set seems to be the only way of
241
+ // knowing whether it's an update or fetch. Only an update would
242
+ // have persistedEdits.
243
+ action.persistedEdits &&
244
+ action.persistedEdits.status !== 'auto-draft' ) ||
245
+ action.type === 'REMOVE_ITEMS' ) &&
246
+ action.kind === 'postType' &&
247
+ action.name === 'wp_template'
248
+ );
249
+ };
250
+
217
251
  export const getTemplateAutoDraftId =
218
252
  ( staticTemplateId ) =>
219
253
  async ( { resolveSelect, dispatch } ) => {
@@ -313,7 +347,26 @@ export const getEntityRecords =
313
347
  };
314
348
  }
315
349
 
316
- const path = addQueryArgs( entityConfig.baseURL, {
350
+ let { baseURL } = entityConfig;
351
+ // `combinedTemplates` means that we fetch templates from the "old"
352
+ // /templates endpoint, which combines active user templates with
353
+ // the registered templates and rewrites IDs in the form of
354
+ // `theme-slug/template-slug`. When turned off, we only fetch
355
+ // database templates (posts). To fetch registered templates without
356
+ // edits applied, use the `wp_registered_template` entity.
357
+ const { combinedTemplates = true } = query;
358
+
359
+ if (
360
+ kind === 'postType' &&
361
+ name === 'wp_template' &&
362
+ combinedTemplates
363
+ ) {
364
+ baseURL =
365
+ baseURL.slice( 0, baseURL.lastIndexOf( '/' ) ) +
366
+ '/templates';
367
+ }
368
+
369
+ const path = addQueryArgs( baseURL, {
317
370
  ...entityConfig.baseURLParams,
318
371
  ...query,
319
372
  } );
@@ -891,7 +944,7 @@ export const getDefaultTemplateId =
891
944
 
892
945
  getDefaultTemplateId.shouldInvalidate = ( action ) => {
893
946
  return (
894
- action.type === 'EDIT_ENTITY_RECORD' &&
947
+ action.type === 'RECEIVE_ITEMS' &&
895
948
  action.kind === 'root' &&
896
949
  action.name === 'site'
897
950
  );
package/src/selectors.ts CHANGED
@@ -358,19 +358,6 @@ export const getEntityRecord = createSelector(
358
358
  query?: GetRecordsHttpQuery
359
359
  ): EntityRecord | undefined => {
360
360
  logEntityDeprecation( kind, name, 'getEntityRecord' );
361
-
362
- // For back-compat, we allow querying for static templates through
363
- // wp_template.
364
- if (
365
- kind === 'postType' &&
366
- name === 'wp_template' &&
367
- typeof key === 'string' &&
368
- // __experimentalGetDirtyEntityRecords always calls getEntityRecord
369
- // with a string key, so we need that it's not a numeric ID.
370
- ! /^\d+$/.test( key )
371
- ) {
372
- name = 'wp_registered_template';
373
- }
374
361
  const queriedState =
375
362
  state.entities.records?.[ kind ]?.[ name ]?.queriedData;
376
363
  if ( ! queriedState ) {
package/src/sync.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ CRDT_RECORD_MAP_KEY,
6
+ LOCAL_EDITOR_ORIGIN,
7
+ LOCAL_SYNC_MANAGER_ORIGIN,
8
+ createSyncManager,
9
+ } from '@wordpress/sync';
10
+
11
+ export { CRDT_RECORD_MAP_KEY, LOCAL_EDITOR_ORIGIN, LOCAL_SYNC_MANAGER_ORIGIN };
12
+ export const syncManager = createSyncManager();