@wordpress/core-data 6.16.0 → 6.17.1

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 (236) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/actions.js +69 -134
  3. package/build/actions.js.map +1 -1
  4. package/build/batch/create-batch.js +0 -22
  5. package/build/batch/create-batch.js.map +1 -1
  6. package/build/batch/default-processor.js +3 -15
  7. package/build/batch/default-processor.js.map +1 -1
  8. package/build/batch/index.js +0 -3
  9. package/build/batch/index.js.map +1 -1
  10. package/build/entities.js +109 -36
  11. package/build/entities.js.map +1 -1
  12. package/build/entity-provider.js +34 -53
  13. package/build/entity-provider.js.map +1 -1
  14. package/build/entity-types/attachment.js.map +1 -1
  15. package/build/entity-types/base-entity-records.js +0 -3
  16. package/build/entity-types/base-entity-records.js.map +1 -1
  17. package/build/entity-types/comment.js.map +1 -1
  18. package/build/entity-types/helpers.js.map +1 -1
  19. package/build/entity-types/index.js.map +1 -1
  20. package/build/entity-types/menu-location.js.map +1 -1
  21. package/build/entity-types/nav-menu-item.js.map +1 -1
  22. package/build/entity-types/nav-menu.js.map +1 -1
  23. package/build/entity-types/page.js.map +1 -1
  24. package/build/entity-types/plugin.js.map +1 -1
  25. package/build/entity-types/post.js.map +1 -1
  26. package/build/entity-types/settings.js.map +1 -1
  27. package/build/entity-types/sidebar.js.map +1 -1
  28. package/build/entity-types/taxonomy.js.map +1 -1
  29. package/build/entity-types/theme.js.map +1 -1
  30. package/build/entity-types/type.js.map +1 -1
  31. package/build/entity-types/user.js.map +1 -1
  32. package/build/entity-types/widget-type.js.map +1 -1
  33. package/build/entity-types/widget.js.map +1 -1
  34. package/build/entity-types/wp-template-part.js.map +1 -1
  35. package/build/entity-types/wp-template.js.map +1 -1
  36. package/build/fetch/__experimental-fetch-link-suggestions.js +14 -20
  37. package/build/fetch/__experimental-fetch-link-suggestions.js.map +1 -1
  38. package/build/fetch/__experimental-fetch-url-data.js +4 -13
  39. package/build/fetch/__experimental-fetch-url-data.js.map +1 -1
  40. package/build/fetch/index.js +0 -3
  41. package/build/fetch/index.js.map +1 -1
  42. package/build/hooks/constants.js +4 -5
  43. package/build/hooks/constants.js.map +1 -1
  44. package/build/hooks/index.js +0 -5
  45. package/build/hooks/index.js.map +1 -1
  46. package/build/hooks/memoize.js +0 -3
  47. package/build/hooks/memoize.js.map +1 -1
  48. package/build/hooks/use-entity-record.js +0 -9
  49. package/build/hooks/use-entity-record.js.map +1 -1
  50. package/build/hooks/use-entity-records.js +2 -9
  51. package/build/hooks/use-entity-records.js.map +1 -1
  52. package/build/hooks/use-query-select.js +1 -13
  53. package/build/hooks/use-query-select.js.map +1 -1
  54. package/build/hooks/use-resource-permissions.js +0 -15
  55. package/build/hooks/use-resource-permissions.js.map +1 -1
  56. package/build/index.js +9 -41
  57. package/build/index.js.map +1 -1
  58. package/build/locks/actions.js +1 -6
  59. package/build/locks/actions.js.map +1 -1
  60. package/build/locks/engine.js +1 -9
  61. package/build/locks/engine.js.map +1 -1
  62. package/build/locks/reducer.js +8 -9
  63. package/build/locks/reducer.js.map +1 -1
  64. package/build/locks/selectors.js +8 -11
  65. package/build/locks/selectors.js.map +1 -1
  66. package/build/locks/utils.js +4 -19
  67. package/build/locks/utils.js.map +1 -1
  68. package/build/name.js +0 -1
  69. package/build/name.js.map +1 -1
  70. package/build/private-apis.js +1 -2
  71. package/build/private-apis.js.map +1 -1
  72. package/build/private-selectors.js +2 -5
  73. package/build/private-selectors.js.map +1 -1
  74. package/build/queried-data/actions.js +4 -6
  75. package/build/queried-data/actions.js.map +1 -1
  76. package/build/queried-data/get-query-parts.js +11 -24
  77. package/build/queried-data/get-query-parts.js.map +1 -1
  78. package/build/queried-data/index.js +0 -6
  79. package/build/queried-data/index.js.map +1 -1
  80. package/build/queried-data/reducer.js +33 -51
  81. package/build/queried-data/reducer.js.map +1 -1
  82. package/build/queried-data/selectors.js +4 -25
  83. package/build/queried-data/selectors.js.map +1 -1
  84. package/build/reducer.js +76 -128
  85. package/build/reducer.js.map +1 -1
  86. package/build/resolvers.js +91 -133
  87. package/build/resolvers.js.map +1 -1
  88. package/build/selectors.js +51 -145
  89. package/build/selectors.js.map +1 -1
  90. package/build/sync.js +19 -0
  91. package/build/sync.js.map +1 -0
  92. package/build/types.js.map +1 -1
  93. package/build/utils/conservative-map-item.js +3 -10
  94. package/build/utils/conservative-map-item.js.map +1 -1
  95. package/build/utils/forward-resolver.js +0 -2
  96. package/build/utils/forward-resolver.js.map +1 -1
  97. package/build/utils/get-normalized-comma-separable.js +0 -3
  98. package/build/utils/get-normalized-comma-separable.js.map +1 -1
  99. package/build/utils/if-matching-action.js +0 -3
  100. package/build/utils/if-matching-action.js.map +1 -1
  101. package/build/utils/index.js +0 -10
  102. package/build/utils/index.js.map +1 -1
  103. package/build/utils/is-raw-attribute.js +0 -1
  104. package/build/utils/is-raw-attribute.js.map +1 -1
  105. package/build/utils/on-sub-key.js +5 -9
  106. package/build/utils/on-sub-key.js.map +1 -1
  107. package/build/utils/replace-action.js +0 -2
  108. package/build/utils/replace-action.js.map +1 -1
  109. package/build/utils/set-nested-value.js +0 -4
  110. package/build/utils/set-nested-value.js.map +1 -1
  111. package/build/utils/with-weak-map-cache.js +3 -6
  112. package/build/utils/with-weak-map-cache.js.map +1 -1
  113. package/build-module/actions.js +72 -95
  114. package/build-module/actions.js.map +1 -1
  115. package/build-module/batch/create-batch.js +1 -20
  116. package/build-module/batch/create-batch.js.map +1 -1
  117. package/build-module/batch/default-processor.js +4 -13
  118. package/build-module/batch/default-processor.js.map +1 -1
  119. package/build-module/batch/index.js.map +1 -1
  120. package/build-module/entities.js +109 -25
  121. package/build-module/entities.js.map +1 -1
  122. package/build-module/entity-provider.js +35 -45
  123. package/build-module/entity-provider.js.map +1 -1
  124. package/build-module/entity-types/attachment.js.map +1 -1
  125. package/build-module/entity-types/base-entity-records.js +0 -2
  126. package/build-module/entity-types/base-entity-records.js.map +1 -1
  127. package/build-module/entity-types/comment.js.map +1 -1
  128. package/build-module/entity-types/helpers.js.map +1 -1
  129. package/build-module/entity-types/index.js.map +1 -1
  130. package/build-module/entity-types/menu-location.js.map +1 -1
  131. package/build-module/entity-types/nav-menu-item.js.map +1 -1
  132. package/build-module/entity-types/nav-menu.js.map +1 -1
  133. package/build-module/entity-types/page.js.map +1 -1
  134. package/build-module/entity-types/plugin.js.map +1 -1
  135. package/build-module/entity-types/post.js.map +1 -1
  136. package/build-module/entity-types/settings.js.map +1 -1
  137. package/build-module/entity-types/sidebar.js.map +1 -1
  138. package/build-module/entity-types/taxonomy.js.map +1 -1
  139. package/build-module/entity-types/theme.js.map +1 -1
  140. package/build-module/entity-types/type.js.map +1 -1
  141. package/build-module/entity-types/user.js.map +1 -1
  142. package/build-module/entity-types/widget-type.js.map +1 -1
  143. package/build-module/entity-types/widget.js.map +1 -1
  144. package/build-module/entity-types/wp-template-part.js.map +1 -1
  145. package/build-module/entity-types/wp-template.js.map +1 -1
  146. package/build-module/fetch/__experimental-fetch-link-suggestions.js +15 -15
  147. package/build-module/fetch/__experimental-fetch-link-suggestions.js.map +1 -1
  148. package/build-module/fetch/__experimental-fetch-url-data.js +5 -10
  149. package/build-module/fetch/__experimental-fetch-url-data.js.map +1 -1
  150. package/build-module/fetch/index.js.map +1 -1
  151. package/build-module/hooks/constants.js +3 -4
  152. package/build-module/hooks/constants.js.map +1 -1
  153. package/build-module/hooks/index.js.map +1 -1
  154. package/build-module/hooks/memoize.js +2 -1
  155. package/build-module/hooks/memoize.js.map +1 -1
  156. package/build-module/hooks/use-entity-record.js +1 -3
  157. package/build-module/hooks/use-entity-record.js.map +1 -1
  158. package/build-module/hooks/use-entity-records.js +2 -3
  159. package/build-module/hooks/use-entity-records.js.map +1 -1
  160. package/build-module/hooks/use-query-select.js +1 -9
  161. package/build-module/hooks/use-query-select.js.map +1 -1
  162. package/build-module/hooks/use-resource-permissions.js +1 -10
  163. package/build-module/hooks/use-resource-permissions.js.map +1 -1
  164. package/build-module/index.js +11 -19
  165. package/build-module/index.js.map +1 -1
  166. package/build-module/locks/actions.js +0 -3
  167. package/build-module/locks/actions.js.map +1 -1
  168. package/build-module/locks/engine.js +0 -5
  169. package/build-module/locks/engine.js.map +1 -1
  170. package/build-module/locks/reducer.js +7 -7
  171. package/build-module/locks/reducer.js.map +1 -1
  172. package/build-module/locks/selectors.js +7 -8
  173. package/build-module/locks/selectors.js.map +1 -1
  174. package/build-module/locks/utils.js +4 -14
  175. package/build-module/locks/utils.js.map +1 -1
  176. package/build-module/name.js.map +1 -1
  177. package/build-module/private-apis.js.map +1 -1
  178. package/build-module/private-selectors.js +2 -2
  179. package/build-module/private-selectors.js.map +1 -1
  180. package/build-module/queried-data/actions.js +4 -3
  181. package/build-module/queried-data/actions.js.map +1 -1
  182. package/build-module/queried-data/get-query-parts.js +13 -21
  183. package/build-module/queried-data/get-query-parts.js.map +1 -1
  184. package/build-module/queried-data/index.js.map +1 -1
  185. package/build-module/queried-data/reducer.js +33 -42
  186. package/build-module/queried-data/reducer.js.map +1 -1
  187. package/build-module/queried-data/selectors.js +6 -21
  188. package/build-module/queried-data/selectors.js.map +1 -1
  189. package/build-module/reducer.js +79 -104
  190. package/build-module/reducer.js.map +1 -1
  191. package/build-module/resolvers.js +94 -96
  192. package/build-module/resolvers.js.map +1 -1
  193. package/build-module/selectors.js +56 -92
  194. package/build-module/selectors.js.map +1 -1
  195. package/build-module/sync.js +12 -0
  196. package/build-module/sync.js.map +1 -0
  197. package/build-module/types.js.map +1 -1
  198. package/build-module/utils/conservative-map-item.js +4 -8
  199. package/build-module/utils/conservative-map-item.js.map +1 -1
  200. package/build-module/utils/forward-resolver.js +0 -1
  201. package/build-module/utils/forward-resolver.js.map +1 -1
  202. package/build-module/utils/get-normalized-comma-separable.js +0 -2
  203. package/build-module/utils/get-normalized-comma-separable.js.map +1 -1
  204. package/build-module/utils/if-matching-action.js +0 -2
  205. package/build-module/utils/if-matching-action.js.map +1 -1
  206. package/build-module/utils/index.js.map +1 -1
  207. package/build-module/utils/is-raw-attribute.js.map +1 -1
  208. package/build-module/utils/on-sub-key.js +5 -7
  209. package/build-module/utils/on-sub-key.js.map +1 -1
  210. package/build-module/utils/replace-action.js +0 -1
  211. package/build-module/utils/replace-action.js.map +1 -1
  212. package/build-module/utils/set-nested-value.js +0 -3
  213. package/build-module/utils/set-nested-value.js.map +1 -1
  214. package/build-module/utils/with-weak-map-cache.js +3 -5
  215. package/build-module/utils/with-weak-map-cache.js.map +1 -1
  216. package/build-types/actions.d.ts.map +1 -1
  217. package/build-types/entities.d.ts +53 -0
  218. package/build-types/entities.d.ts.map +1 -1
  219. package/build-types/entity-provider.d.ts +1 -1
  220. package/build-types/entity-provider.d.ts.map +1 -1
  221. package/build-types/hooks/memoize.d.ts +1 -1
  222. package/build-types/hooks/memoize.d.ts.map +1 -1
  223. package/build-types/index.d.ts +3 -3
  224. package/build-types/index.d.ts.map +1 -1
  225. package/build-types/resolvers.d.ts.map +1 -1
  226. package/build-types/sync.d.ts +2 -0
  227. package/build-types/sync.d.ts.map +1 -0
  228. package/package.json +17 -15
  229. package/src/actions.js +24 -14
  230. package/src/entities.js +91 -0
  231. package/src/entity-provider.js +11 -2
  232. package/src/resolvers.js +89 -41
  233. package/src/sync.js +18 -0
  234. package/src/test/entity-provider.js +272 -0
  235. package/tsconfig.json +1 -0
  236. package/tsconfig.tsbuildinfo +1 -1
@@ -2,26 +2,27 @@
2
2
  * External dependencies
3
3
  */
4
4
  import { camelCase } from 'change-case';
5
+
5
6
  /**
6
7
  * WordPress dependencies
7
8
  */
8
-
9
9
  import { addQueryArgs } from '@wordpress/url';
10
10
  import apiFetch from '@wordpress/api-fetch';
11
+
11
12
  /**
12
13
  * Internal dependencies
13
14
  */
14
-
15
15
  import { STORE_NAME } from './name';
16
16
  import { getOrLoadEntitiesConfig, DEFAULT_ENTITY_KEY } from './entities';
17
17
  import { forwardResolver, getNormalizedCommaSeparable } from './utils';
18
+ import { getSyncProvider } from './sync';
19
+
18
20
  /**
19
21
  * Requests authors from the REST API.
20
22
  *
21
23
  * @param {Object|undefined} query Optional object of query parameters to
22
24
  * include with request.
23
25
  */
24
-
25
26
  export const getAuthors = query => async ({
26
27
  dispatch
27
28
  }) => {
@@ -31,10 +32,10 @@ export const getAuthors = query => async ({
31
32
  });
32
33
  dispatch.receiveUserQuery(path, users);
33
34
  };
35
+
34
36
  /**
35
37
  * Requests the current user from the REST API.
36
38
  */
37
-
38
39
  export const getCurrentUser = () => async ({
39
40
  dispatch
40
41
  }) => {
@@ -43,6 +44,7 @@ export const getCurrentUser = () => async ({
43
44
  });
44
45
  dispatch.receiveCurrentUser(currentUser);
45
46
  };
47
+
46
48
  /**
47
49
  * Requests an entity's record from the REST API.
48
50
  *
@@ -53,74 +55,98 @@ export const getCurrentUser = () => async ({
53
55
  * include with request. If requesting specific
54
56
  * fields, fields must always include the ID.
55
57
  */
56
-
57
58
  export const getEntityRecord = (kind, name, key = '', query) => async ({
58
59
  select,
59
60
  dispatch
60
61
  }) => {
61
62
  const configs = await dispatch(getOrLoadEntitiesConfig(kind));
62
63
  const entityConfig = configs.find(config => config.name === name && config.kind === kind);
63
-
64
64
  if (!entityConfig || entityConfig?.__experimentalNoFetch) {
65
65
  return;
66
66
  }
67
-
68
67
  const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'records', kind, name, key], {
69
68
  exclusive: false
70
69
  });
71
-
72
70
  try {
73
- if (query !== undefined && query._fields) {
74
- // If requesting specific fields, items and query association to said
75
- // records are stored by ID reference. Thus, fields must always include
76
- // the ID.
77
- query = { ...query,
78
- _fields: [...new Set([...(getNormalizedCommaSeparable(query._fields) || []), entityConfig.key || DEFAULT_ENTITY_KEY])].join()
79
- };
80
- } // Disable reason: While true that an early return could leave `path`
81
- // unused, it's important that path is derived using the query prior to
82
- // additional query modifications in the condition below, since those
83
- // modifications are relevant to how the data is tracked in state, and not
84
- // for how the request is made to the REST API.
85
- // eslint-disable-next-line @wordpress/no-unused-vars-before-return
86
-
87
-
88
- const path = addQueryArgs(entityConfig.baseURL + (key ? '/' + key : ''), { ...entityConfig.baseURLParams,
89
- ...query
90
- });
71
+ // Entity supports configs,
72
+ // use the sync algorithm instead of the old fetch behavior.
73
+ if (window.__experimentalEnableSync && entityConfig.syncConfig && !query) {
74
+ const objectId = entityConfig.getSyncObjectId(key);
75
+
76
+ // Loads the persisted document.
77
+ await getSyncProvider().bootstrap(entityConfig.syncObjectType, objectId, record => {
78
+ dispatch.receiveEntityRecords(kind, name, record, query);
79
+ });
91
80
 
92
- if (query !== undefined) {
93
- query = { ...query,
94
- include: [key]
95
- }; // The resolution cache won't consider query as reusable based on the
96
- // fields, so it's tested here, prior to initiating the REST request,
97
- // and without causing `getEntityRecords` resolution to occur.
81
+ // Boostraps the edited document as well (and load from peers).
82
+ await getSyncProvider().bootstrap(entityConfig.syncObjectType + '--edit', objectId, record => {
83
+ dispatch({
84
+ type: 'EDIT_ENTITY_RECORD',
85
+ kind,
86
+ name,
87
+ recordId: key,
88
+ edits: record,
89
+ meta: {
90
+ undo: undefined
91
+ }
92
+ });
93
+ });
94
+ } else {
95
+ if (query !== undefined && query._fields) {
96
+ // If requesting specific fields, items and query association to said
97
+ // records are stored by ID reference. Thus, fields must always include
98
+ // the ID.
99
+ query = {
100
+ ...query,
101
+ _fields: [...new Set([...(getNormalizedCommaSeparable(query._fields) || []), entityConfig.key || DEFAULT_ENTITY_KEY])].join()
102
+ };
103
+ }
98
104
 
99
- const hasRecords = select.hasEntityRecords(kind, name, query);
105
+ // Disable reason: While true that an early return could leave `path`
106
+ // unused, it's important that path is derived using the query prior to
107
+ // additional query modifications in the condition below, since those
108
+ // modifications are relevant to how the data is tracked in state, and not
109
+ // for how the request is made to the REST API.
100
110
 
101
- if (hasRecords) {
102
- return;
111
+ // eslint-disable-next-line @wordpress/no-unused-vars-before-return
112
+ const path = addQueryArgs(entityConfig.baseURL + (key ? '/' + key : ''), {
113
+ ...entityConfig.baseURLParams,
114
+ ...query
115
+ });
116
+ if (query !== undefined) {
117
+ query = {
118
+ ...query,
119
+ include: [key]
120
+ };
121
+
122
+ // The resolution cache won't consider query as reusable based on the
123
+ // fields, so it's tested here, prior to initiating the REST request,
124
+ // and without causing `getEntityRecords` resolution to occur.
125
+ const hasRecords = select.hasEntityRecords(kind, name, query);
126
+ if (hasRecords) {
127
+ return;
128
+ }
103
129
  }
130
+ const record = await apiFetch({
131
+ path
132
+ });
133
+ dispatch.receiveEntityRecords(kind, name, record, query);
104
134
  }
105
-
106
- const record = await apiFetch({
107
- path
108
- });
109
- dispatch.receiveEntityRecords(kind, name, record, query);
110
135
  } finally {
111
136
  dispatch.__unstableReleaseStoreLock(lock);
112
137
  }
113
138
  };
139
+
114
140
  /**
115
141
  * Requests an entity's record from the REST API.
116
142
  */
117
-
118
143
  export const getRawEntityRecord = forwardResolver('getEntityRecord');
144
+
119
145
  /**
120
146
  * Requests an entity's record from the REST API.
121
147
  */
122
-
123
148
  export const getEditedEntityRecord = forwardResolver('getEntityRecord');
149
+
124
150
  /**
125
151
  * Requests the entity's records from the REST API.
126
152
  *
@@ -129,40 +155,37 @@ export const getEditedEntityRecord = forwardResolver('getEntityRecord');
129
155
  * @param {Object?} query Query Object. If requesting specific fields, fields
130
156
  * must always include the ID.
131
157
  */
132
-
133
158
  export const getEntityRecords = (kind, name, query = {}) => async ({
134
159
  dispatch
135
160
  }) => {
136
161
  const configs = await dispatch(getOrLoadEntitiesConfig(kind));
137
162
  const entityConfig = configs.find(config => config.name === name && config.kind === kind);
138
-
139
163
  if (!entityConfig || entityConfig?.__experimentalNoFetch) {
140
164
  return;
141
165
  }
142
-
143
166
  const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'records', kind, name], {
144
167
  exclusive: false
145
168
  });
146
-
147
169
  try {
148
170
  if (query._fields) {
149
171
  // If requesting specific fields, items and query association to said
150
172
  // records are stored by ID reference. Thus, fields must always include
151
173
  // the ID.
152
- query = { ...query,
174
+ query = {
175
+ ...query,
153
176
  _fields: [...new Set([...(getNormalizedCommaSeparable(query._fields) || []), entityConfig.key || DEFAULT_ENTITY_KEY])].join()
154
177
  };
155
178
  }
156
-
157
- const path = addQueryArgs(entityConfig.baseURL, { ...entityConfig.baseURLParams,
179
+ const path = addQueryArgs(entityConfig.baseURL, {
180
+ ...entityConfig.baseURLParams,
158
181
  ...query
159
182
  });
160
183
  let records = Object.values(await apiFetch({
161
184
  path
162
- })); // If we request fields but the result doesn't contain the fields,
185
+ }));
186
+ // If we request fields but the result doesn't contain the fields,
163
187
  // explicitly set these fields as "undefined"
164
188
  // that way we consider the query "fullfilled".
165
-
166
189
  if (query._fields) {
167
190
  records = records.map(record => {
168
191
  query._fields.split(',').forEach(field => {
@@ -170,15 +193,14 @@ export const getEntityRecords = (kind, name, query = {}) => async ({
170
193
  record[field] = undefined;
171
194
  }
172
195
  });
173
-
174
196
  return record;
175
197
  });
176
198
  }
199
+ dispatch.receiveEntityRecords(kind, name, records, query);
177
200
 
178
- dispatch.receiveEntityRecords(kind, name, records, query); // When requesting all fields, the list of results can be used to
201
+ // When requesting all fields, the list of results can be used to
179
202
  // resolve the `getEntityRecord` selector in addition to `getEntityRecords`.
180
203
  // See https://github.com/WordPress/gutenberg/pull/26575
181
-
182
204
  if (!query?._fields && !query.context) {
183
205
  const key = entityConfig.key || DEFAULT_ENTITY_KEY;
184
206
  const resolutionsArgs = records.filter(record => record[key]).map(record => [kind, name, record[key]]);
@@ -197,15 +219,13 @@ export const getEntityRecords = (kind, name, query = {}) => async ({
197
219
  dispatch.__unstableReleaseStoreLock(lock);
198
220
  }
199
221
  };
200
-
201
222
  getEntityRecords.shouldInvalidate = (action, kind, name) => {
202
223
  return (action.type === 'RECEIVE_ITEMS' || action.type === 'REMOVE_ITEMS') && action.invalidateCache && kind === action.kind && name === action.name;
203
224
  };
225
+
204
226
  /**
205
227
  * Requests the current theme.
206
228
  */
207
-
208
-
209
229
  export const getCurrentTheme = () => async ({
210
230
  dispatch,
211
231
  resolveSelect
@@ -215,17 +235,17 @@ export const getCurrentTheme = () => async ({
215
235
  });
216
236
  dispatch.receiveCurrentTheme(activeThemes[0]);
217
237
  };
238
+
218
239
  /**
219
240
  * Requests theme supports data from the index.
220
241
  */
221
-
222
242
  export const getThemeSupports = forwardResolver('getCurrentTheme');
243
+
223
244
  /**
224
245
  * Requests a preview from the from the Embed API.
225
246
  *
226
247
  * @param {string} url URL to get the preview for.
227
248
  */
228
-
229
249
  export const getEmbedPreview = url => async ({
230
250
  dispatch
231
251
  }) => {
@@ -241,6 +261,7 @@ export const getEmbedPreview = url => async ({
241
261
  dispatch.receiveEmbedPreview(url, false);
242
262
  }
243
263
  };
264
+
244
265
  /**
245
266
  * Checks whether the current user can perform the given action on the given
246
267
  * REST resource.
@@ -250,7 +271,6 @@ export const getEmbedPreview = url => async ({
250
271
  * @param {string} resource REST resource to check, e.g. 'media' or 'posts'.
251
272
  * @param {?string} id ID of the rest resource to check.
252
273
  */
253
-
254
274
  export const canUser = (requestedAction, resource, id) => async ({
255
275
  dispatch,
256
276
  registry
@@ -260,26 +280,21 @@ export const canUser = (requestedAction, resource, id) => async ({
260
280
  } = registry.select(STORE_NAME);
261
281
  const resourcePath = id ? `${resource}/${id}` : resource;
262
282
  const retrievedActions = ['create', 'read', 'update', 'delete'];
263
-
264
283
  if (!retrievedActions.includes(requestedAction)) {
265
284
  throw new Error(`'${requestedAction}' is not a valid action.`);
266
- } // Prevent resolving the same resource twice.
267
-
285
+ }
268
286
 
287
+ // Prevent resolving the same resource twice.
269
288
  for (const relatedAction of retrievedActions) {
270
289
  if (relatedAction === requestedAction) {
271
290
  continue;
272
291
  }
273
-
274
292
  const isAlreadyResolving = hasStartedResolution('canUser', [relatedAction, resource, id]);
275
-
276
293
  if (isAlreadyResolving) {
277
294
  return;
278
295
  }
279
296
  }
280
-
281
297
  let response;
282
-
283
298
  try {
284
299
  response = await apiFetch({
285
300
  path: `/wp/v2/${resourcePath}`,
@@ -290,11 +305,11 @@ export const canUser = (requestedAction, resource, id) => async ({
290
305
  // Do nothing if our OPTIONS request comes back with an API error (4xx or
291
306
  // 5xx). The previously determined isAllowed value will remain in the store.
292
307
  return;
293
- } // Optional chaining operator is used here because the API requests don't
308
+ }
309
+
310
+ // Optional chaining operator is used here because the API requests don't
294
311
  // return the expected result in the native version. Instead, API requests
295
312
  // only return the result, without including response properties like the headers.
296
-
297
-
298
313
  const allowHeader = response.headers?.get('allow');
299
314
  const allowedMethods = allowHeader?.allow || allowHeader || '';
300
315
  const permissions = {};
@@ -304,15 +319,14 @@ export const canUser = (requestedAction, resource, id) => async ({
304
319
  update: 'PUT',
305
320
  delete: 'DELETE'
306
321
  };
307
-
308
322
  for (const [actionName, methodName] of Object.entries(methods)) {
309
323
  permissions[actionName] = allowedMethods.includes(methodName);
310
324
  }
311
-
312
325
  for (const action of retrievedActions) {
313
326
  dispatch.receiveUserPermission(`${action}/${resourcePath}`, permissions[action]);
314
327
  }
315
328
  };
329
+
316
330
  /**
317
331
  * Checks whether the current user can perform the given action on the given
318
332
  * REST resource.
@@ -321,27 +335,24 @@ export const canUser = (requestedAction, resource, id) => async ({
321
335
  * @param {string} name Entity name.
322
336
  * @param {string} recordId Record's id.
323
337
  */
324
-
325
338
  export const canUserEditEntityRecord = (kind, name, recordId) => async ({
326
339
  dispatch
327
340
  }) => {
328
341
  const configs = await dispatch(getOrLoadEntitiesConfig(kind));
329
342
  const entityConfig = configs.find(config => config.name === name && config.kind === kind);
330
-
331
343
  if (!entityConfig) {
332
344
  return;
333
345
  }
334
-
335
346
  const resource = entityConfig.__unstable_rest_base;
336
347
  await dispatch(canUser('update', resource, recordId));
337
348
  };
349
+
338
350
  /**
339
351
  * Request autosave data from the REST API.
340
352
  *
341
353
  * @param {string} postType The type of the parent post.
342
354
  * @param {number} postId The id of the parent post.
343
355
  */
344
-
345
356
  export const getAutosaves = (postType, postId) => async ({
346
357
  dispatch,
347
358
  resolveSelect
@@ -353,11 +364,11 @@ export const getAutosaves = (postType, postId) => async ({
353
364
  const autosaves = await apiFetch({
354
365
  path: `/${restNamespace}/${restBase}/${postId}/autosaves?context=edit`
355
366
  });
356
-
357
367
  if (autosaves && autosaves.length) {
358
368
  dispatch.receiveAutosaves(postId, autosaves);
359
369
  }
360
370
  };
371
+
361
372
  /**
362
373
  * Request autosave data from the REST API.
363
374
  *
@@ -367,24 +378,22 @@ export const getAutosaves = (postType, postId) => async ({
367
378
  * @param {string} postType The type of the parent post.
368
379
  * @param {number} postId The id of the parent post.
369
380
  */
370
-
371
381
  export const getAutosave = (postType, postId) => async ({
372
382
  resolveSelect
373
383
  }) => {
374
384
  await resolveSelect.getAutosaves(postType, postId);
375
385
  };
386
+
376
387
  /**
377
388
  * Retrieve the frontend template used for a given link.
378
389
  *
379
390
  * @param {string} link Link.
380
391
  */
381
-
382
392
  export const __experimentalGetTemplateForLink = link => async ({
383
393
  dispatch,
384
394
  resolveSelect
385
395
  }) => {
386
396
  let template;
387
-
388
397
  try {
389
398
  // This is NOT calling a REST endpoint but rather ends up with a response from
390
399
  // an Ajax function which has a different shape from a WP_REST_Response.
@@ -395,26 +404,22 @@ export const __experimentalGetTemplateForLink = link => async ({
395
404
  }).then(({
396
405
  data
397
406
  }) => data);
398
- } catch (e) {// For non-FSE themes, it is possible that this request returns an error.
407
+ } catch (e) {
408
+ // For non-FSE themes, it is possible that this request returns an error.
399
409
  }
400
-
401
410
  if (!template) {
402
411
  return;
403
412
  }
404
-
405
413
  const record = await resolveSelect.getEntityRecord('postType', 'wp_template', template.id);
406
-
407
414
  if (record) {
408
415
  dispatch.receiveEntityRecords('postType', 'wp_template', [record], {
409
416
  'find-template': link
410
417
  });
411
418
  }
412
419
  };
413
-
414
420
  __experimentalGetTemplateForLink.shouldInvalidate = action => {
415
421
  return (action.type === 'RECEIVE_ITEMS' || action.type === 'REMOVE_ITEMS') && action.invalidateCache && action.kind === 'postType' && action.name === 'wp_template';
416
422
  };
417
-
418
423
  export const __experimentalGetCurrentGlobalStylesId = () => async ({
419
424
  dispatch,
420
425
  resolveSelect
@@ -423,12 +428,10 @@ export const __experimentalGetCurrentGlobalStylesId = () => async ({
423
428
  status: 'active'
424
429
  });
425
430
  const globalStylesURL = activeThemes?.[0]?._links?.['wp:user-global-styles']?.[0]?.href;
426
-
427
431
  if (globalStylesURL) {
428
432
  const globalStylesObject = await apiFetch({
429
433
  url: globalStylesURL
430
434
  });
431
-
432
435
  dispatch.__experimentalReceiveCurrentGlobalStylesId(globalStylesObject.id);
433
436
  }
434
437
  };
@@ -440,7 +443,6 @@ export const __experimentalGetCurrentThemeBaseGlobalStyles = () => async ({
440
443
  const themeGlobalStyles = await apiFetch({
441
444
  path: `/wp/v2/global-styles/themes/${currentTheme.stylesheet}`
442
445
  });
443
-
444
446
  dispatch.__experimentalReceiveThemeBaseGlobalStyles(currentTheme.stylesheet, themeGlobalStyles);
445
447
  };
446
448
  export const __experimentalGetCurrentThemeGlobalStylesVariations = () => async ({
@@ -451,13 +453,12 @@ export const __experimentalGetCurrentThemeGlobalStylesVariations = () => async (
451
453
  const variations = await apiFetch({
452
454
  path: `/wp/v2/global-styles/themes/${currentTheme.stylesheet}/variations`
453
455
  });
454
-
455
456
  dispatch.__experimentalReceiveThemeGlobalStyleVariations(currentTheme.stylesheet, variations);
456
457
  };
458
+
457
459
  /**
458
460
  * Fetches and returns the revisions of the current global styles theme.
459
461
  */
460
-
461
462
  export const getCurrentThemeGlobalStylesRevisions = () => async ({
462
463
  resolveSelect,
463
464
  dispatch
@@ -465,7 +466,6 @@ export const getCurrentThemeGlobalStylesRevisions = () => async ({
465
466
  const globalStylesId = await resolveSelect.__experimentalGetCurrentGlobalStylesId();
466
467
  const record = globalStylesId ? await resolveSelect.getEntityRecord('root', 'globalStyles', globalStylesId) : undefined;
467
468
  const revisionsURL = record?._links?.['version-history']?.[0]?.href;
468
-
469
469
  if (revisionsURL) {
470
470
  const resetRevisions = await apiFetch({
471
471
  url: revisionsURL
@@ -474,11 +474,9 @@ export const getCurrentThemeGlobalStylesRevisions = () => async ({
474
474
  dispatch.receiveThemeGlobalStyleRevisions(globalStylesId, revisions);
475
475
  }
476
476
  };
477
-
478
477
  getCurrentThemeGlobalStylesRevisions.shouldInvalidate = action => {
479
478
  return action.type === 'SAVE_ENTITY_RECORD_FINISH' && action.kind === 'root' && !action.error && action.name === 'globalStyles';
480
479
  };
481
-
482
480
  export const getBlockPatterns = () => async ({
483
481
  dispatch
484
482
  }) => {
@@ -513,15 +511,15 @@ export const getNavigationFallbackId = () => async ({
513
511
  });
514
512
  const record = fallback?._embedded?.self;
515
513
  dispatch.receiveNavigationFallbackId(fallback?.id);
516
-
517
514
  if (record) {
518
515
  // If the fallback is already in the store, don't invalidate navigation queries.
519
516
  // Otherwise, invalidate the cache for the scenario where there were no Navigation
520
517
  // posts in the state and the fallback created one.
521
518
  const existingFallbackEntityRecord = select.getEntityRecord('postType', 'wp_navigation', fallback?.id);
522
519
  const invalidateNavigationQueries = !existingFallbackEntityRecord;
523
- dispatch.receiveEntityRecords('postType', 'wp_navigation', record, undefined, invalidateNavigationQueries); // Resolve to avoid further network requests.
520
+ dispatch.receiveEntityRecords('postType', 'wp_navigation', record, undefined, invalidateNavigationQueries);
524
521
 
522
+ // Resolve to avoid further network requests.
525
523
  dispatch.finishResolution('getEntityRecord', ['postType', 'wp_navigation', fallback?.id]);
526
524
  }
527
525
  };