@wordpress/core-data 4.0.1 → 4.0.5

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 (116) hide show
  1. package/README.md +13 -7
  2. package/build/actions.js +178 -122
  3. package/build/actions.js.map +1 -1
  4. package/build/batch/default-processor.js +58 -27
  5. package/build/batch/default-processor.js.map +1 -1
  6. package/build/entities.js +70 -23
  7. package/build/entities.js.map +1 -1
  8. package/build/fetch/__experimental-fetch-url-data.js +1 -1
  9. package/build/fetch/__experimental-fetch-url-data.js.map +1 -1
  10. package/build/index.js +9 -17
  11. package/build/index.js.map +1 -1
  12. package/build/locks/actions.js +17 -77
  13. package/build/locks/actions.js.map +1 -1
  14. package/build/locks/engine.js +77 -0
  15. package/build/locks/engine.js.map +1 -0
  16. package/build/locks/reducer.js +1 -5
  17. package/build/locks/reducer.js.map +1 -1
  18. package/build/locks/selectors.js +6 -6
  19. package/build/locks/selectors.js.map +1 -1
  20. package/build/queried-data/get-query-parts.js +9 -4
  21. package/build/queried-data/get-query-parts.js.map +1 -1
  22. package/build/queried-data/selectors.js +3 -9
  23. package/build/queried-data/selectors.js.map +1 -1
  24. package/build/reducer.js +17 -22
  25. package/build/reducer.js.map +1 -1
  26. package/build/resolvers.js +151 -97
  27. package/build/resolvers.js.map +1 -1
  28. package/build/selectors.js +79 -14
  29. package/build/selectors.js.map +1 -1
  30. package/build/utils/forward-resolver.js +23 -0
  31. package/build/utils/forward-resolver.js.map +1 -0
  32. package/build/utils/index.js +11 -3
  33. package/build/utils/index.js.map +1 -1
  34. package/build/utils/is-raw-attribute.js +19 -0
  35. package/build/utils/is-raw-attribute.js.map +1 -0
  36. package/build-module/actions.js +155 -112
  37. package/build-module/actions.js.map +1 -1
  38. package/build-module/batch/default-processor.js +57 -27
  39. package/build-module/batch/default-processor.js.map +1 -1
  40. package/build-module/entities.js +65 -19
  41. package/build-module/entities.js.map +1 -1
  42. package/build-module/fetch/__experimental-fetch-url-data.js +1 -1
  43. package/build-module/fetch/__experimental-fetch-url-data.js.map +1 -1
  44. package/build-module/index.js +10 -14
  45. package/build-module/index.js.map +1 -1
  46. package/build-module/locks/actions.js +14 -68
  47. package/build-module/locks/actions.js.map +1 -1
  48. package/build-module/locks/engine.js +66 -0
  49. package/build-module/locks/engine.js.map +1 -0
  50. package/build-module/locks/reducer.js +1 -2
  51. package/build-module/locks/reducer.js.map +1 -1
  52. package/build-module/locks/selectors.js +4 -4
  53. package/build-module/locks/selectors.js.map +1 -1
  54. package/build-module/queried-data/get-query-parts.js +9 -4
  55. package/build-module/queried-data/get-query-parts.js.map +1 -1
  56. package/build-module/queried-data/selectors.js +3 -9
  57. package/build-module/queried-data/selectors.js.map +1 -1
  58. package/build-module/reducer.js +15 -19
  59. package/build-module/reducer.js.map +1 -1
  60. package/build-module/resolvers.js +123 -81
  61. package/build-module/resolvers.js.map +1 -1
  62. package/build-module/selectors.js +74 -13
  63. package/build-module/selectors.js.map +1 -1
  64. package/build-module/utils/forward-resolver.js +15 -0
  65. package/build-module/utils/forward-resolver.js.map +1 -0
  66. package/build-module/utils/index.js +2 -1
  67. package/build-module/utils/index.js.map +1 -1
  68. package/build-module/utils/is-raw-attribute.js +12 -0
  69. package/build-module/utils/is-raw-attribute.js.map +1 -0
  70. package/package.json +10 -11
  71. package/src/actions.js +163 -194
  72. package/src/batch/default-processor.js +57 -26
  73. package/src/batch/test/default-processor.js +53 -26
  74. package/src/entities.js +47 -19
  75. package/src/fetch/__experimental-fetch-url-data.js +1 -1
  76. package/src/index.js +7 -10
  77. package/src/locks/actions.js +10 -61
  78. package/src/locks/engine.js +43 -0
  79. package/src/locks/reducer.js +1 -3
  80. package/src/locks/selectors.js +4 -4
  81. package/src/locks/test/engine.js +135 -0
  82. package/src/locks/test/reducer.js +1 -1
  83. package/src/locks/test/selectors.js +105 -124
  84. package/src/queried-data/get-query-parts.js +11 -6
  85. package/src/queried-data/selectors.js +2 -9
  86. package/src/queried-data/test/get-query-parts.js +1 -1
  87. package/src/queried-data/test/selectors.js +1 -0
  88. package/src/reducer.js +14 -19
  89. package/src/resolvers.js +132 -120
  90. package/src/selectors.js +156 -44
  91. package/src/test/actions.js +330 -170
  92. package/src/test/entities.js +40 -26
  93. package/src/test/resolvers.js +270 -223
  94. package/src/test/selectors.js +127 -1
  95. package/src/utils/forward-resolver.js +14 -0
  96. package/src/utils/index.js +2 -1
  97. package/src/utils/is-raw-attribute.js +11 -0
  98. package/src/utils/test/is-raw-attribute.js +22 -0
  99. package/build/controls.js +0 -44
  100. package/build/controls.js.map +0 -1
  101. package/build/locks/index.js +0 -47
  102. package/build/locks/index.js.map +0 -1
  103. package/build/utils/if-not-resolved.js +0 -46
  104. package/build/utils/if-not-resolved.js.map +0 -1
  105. package/build-module/controls.js +0 -31
  106. package/build-module/controls.js.map +0 -1
  107. package/build-module/locks/index.js +0 -4
  108. package/build-module/locks/index.js.map +0 -1
  109. package/build-module/utils/if-not-resolved.js +0 -36
  110. package/build-module/utils/if-not-resolved.js.map +0 -1
  111. package/src/controls.js +0 -31
  112. package/src/locks/index.js +0 -3
  113. package/src/locks/test/actions.js +0 -307
  114. package/src/test/integration.js +0 -264
  115. package/src/utils/if-not-resolved.js +0 -40
  116. package/src/utils/test/if-not-resolved.js +0 -75
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["@wordpress/core-data/src/utils/is-raw-attribute.js"],"names":["isRawAttribute","entity","attribute","rawAttributes","includes"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASA,cAAT,CAAyBC,MAAzB,EAAiCC,SAAjC,EAA6C;AAC3D,SAAO,CAAED,MAAM,CAACE,aAAP,IAAwB,EAA1B,EAA+BC,QAA/B,CAAyCF,SAAzC,CAAP;AACA","sourcesContent":["/**\n * Checks whether the attribute is a \"raw\" attribute or not.\n *\n * @param {Object} entity Entity data.\n * @param {string} attribute Attribute name.\n *\n * @return {boolean} Is the attribute raw\n */\nexport default function isRawAttribute( entity, attribute ) {\n\treturn ( entity.rawAttributes || [] ).includes( attribute );\n}\n"]}
@@ -1,24 +1,22 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { castArray, get, isEqual, find } from 'lodash';
4
+ import { castArray, isEqual, find } from 'lodash';
5
5
  import { v4 as uuid } from 'uuid';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
9
 
10
- import { controls } from '@wordpress/data';
11
- import { apiFetch, __unstableAwaitPromise } from '@wordpress/data-controls';
10
+ import apiFetch from '@wordpress/api-fetch';
12
11
  import { addQueryArgs } from '@wordpress/url';
12
+ import deprecated from '@wordpress/deprecated';
13
13
  /**
14
14
  * Internal dependencies
15
15
  */
16
16
 
17
17
  import { receiveItems, removeItems, receiveQueriedItems } from './queried-data';
18
18
  import { getKindEntities, DEFAULT_ENTITY_KEY } from './entities';
19
- import { __unstableAcquireStoreLock, __unstableReleaseStoreLock } from './locks';
20
19
  import { createBatch } from './batch';
21
- import { getDispatch } from './controls';
22
20
  import { STORE_NAME } from './name';
23
21
  /**
24
22
  * Returns an action object used in signalling that authors have been received.
@@ -113,18 +111,50 @@ export function receiveCurrentTheme(currentTheme) {
113
111
  currentTheme
114
112
  };
115
113
  }
114
+ /**
115
+ * Returns an action object used in signalling that the current global styles id has been received.
116
+ *
117
+ * @param {string} currentGlobalStylesId The current global styles id.
118
+ *
119
+ * @return {Object} Action object.
120
+ */
121
+
122
+ export function __experimentalReceiveCurrentGlobalStylesId(currentGlobalStylesId) {
123
+ return {
124
+ type: 'RECEIVE_CURRENT_GLOBAL_STYLES_ID',
125
+ id: currentGlobalStylesId
126
+ };
127
+ }
128
+ /**
129
+ * Returns an action object used in signalling that the theme base global styles have been received
130
+ *
131
+ * @param {string} stylesheet The theme's identifier
132
+ * @param {Object} globalStyles The global styles object.
133
+ *
134
+ * @return {Object} Action object.
135
+ */
136
+
137
+ export function __experimentalReceiveThemeBaseGlobalStyles(stylesheet, globalStyles) {
138
+ return {
139
+ type: 'RECEIVE_THEME_GLOBAL_STYLES',
140
+ stylesheet,
141
+ globalStyles
142
+ };
143
+ }
116
144
  /**
117
145
  * Returns an action object used in signalling that the index has been received.
118
146
  *
119
- * @param {Object} themeSupports Theme support for the current theme.
147
+ * @deprecated since WP 5.9, this is not useful anymore, use the selector direclty.
120
148
  *
121
149
  * @return {Object} Action object.
122
150
  */
123
151
 
124
- export function receiveThemeSupports(themeSupports) {
152
+ export function receiveThemeSupports() {
153
+ deprecated("wp.data.dispatch( 'core' ).receiveThemeSupports", {
154
+ since: '5.9'
155
+ });
125
156
  return {
126
- type: 'RECEIVE_THEME_SUPPORTS',
127
- themeSupports
157
+ type: 'DO_NOTHING'
128
158
  };
129
159
  }
130
160
  /**
@@ -155,13 +185,15 @@ export function receiveEmbedPreview(url, preview) {
155
185
  * @param {Object} [options] Delete options.
156
186
  * @param {Function} [options.__unstableFetch] Internal use only. Function to
157
187
  * call instead of `apiFetch()`.
158
- * Must return a control descriptor.
188
+ * Must return a promise.
159
189
  */
160
190
 
161
- export function* deleteEntityRecord(kind, name, recordId, query, {
162
- __unstableFetch = null
163
- } = {}) {
164
- const entities = yield getKindEntities(kind);
191
+ export const deleteEntityRecord = (kind, name, recordId, query, {
192
+ __unstableFetch = apiFetch
193
+ } = {}) => async ({
194
+ dispatch
195
+ }) => {
196
+ const entities = await dispatch(getKindEntities(kind));
165
197
  const entity = find(entities, {
166
198
  kind,
167
199
  name
@@ -169,21 +201,21 @@ export function* deleteEntityRecord(kind, name, recordId, query, {
169
201
  let error;
170
202
  let deletedRecord = false;
171
203
 
172
- if (!entity) {
204
+ if (!entity || entity !== null && entity !== void 0 && entity.__experimentalNoFetch) {
173
205
  return;
174
206
  }
175
207
 
176
- const lock = yield* __unstableAcquireStoreLock(STORE_NAME, ['entities', 'data', kind, name, recordId], {
208
+ const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'data', kind, name, recordId], {
177
209
  exclusive: true
178
210
  });
179
211
 
180
212
  try {
181
- yield {
213
+ dispatch({
182
214
  type: 'DELETE_ENTITY_RECORD_START',
183
215
  kind,
184
216
  name,
185
217
  recordId
186
- };
218
+ });
187
219
 
188
220
  try {
189
221
  let path = `${entity.baseURL}/${recordId}`;
@@ -192,34 +224,27 @@ export function* deleteEntityRecord(kind, name, recordId, query, {
192
224
  path = addQueryArgs(path, query);
193
225
  }
194
226
 
195
- const options = {
227
+ deletedRecord = await __unstableFetch({
196
228
  path,
197
229
  method: 'DELETE'
198
- };
199
-
200
- if (__unstableFetch) {
201
- deletedRecord = yield __unstableAwaitPromise(__unstableFetch(options));
202
- } else {
203
- deletedRecord = yield apiFetch(options);
204
- }
205
-
206
- yield removeItems(kind, name, recordId, true);
230
+ });
231
+ await dispatch(removeItems(kind, name, recordId, true));
207
232
  } catch (_error) {
208
233
  error = _error;
209
234
  }
210
235
 
211
- yield {
236
+ dispatch({
212
237
  type: 'DELETE_ENTITY_RECORD_FINISH',
213
238
  kind,
214
239
  name,
215
240
  recordId,
216
241
  error
217
- };
242
+ });
218
243
  return deletedRecord;
219
244
  } finally {
220
- yield* __unstableReleaseStoreLock(lock);
245
+ dispatch.__unstableReleaseStoreLock(lock);
221
246
  }
222
- }
247
+ };
223
248
  /**
224
249
  * Returns an action object that triggers an
225
250
  * edit to an entity record.
@@ -234,8 +259,11 @@ export function* deleteEntityRecord(kind, name, recordId, query, {
234
259
  * @return {Object} Action object.
235
260
  */
236
261
 
237
- export function* editEntityRecord(kind, name, recordId, edits, options = {}) {
238
- const entity = yield controls.select(STORE_NAME, 'getEntity', kind, name);
262
+ export const editEntityRecord = (kind, name, recordId, edits, options = {}) => ({
263
+ select,
264
+ dispatch
265
+ }) => {
266
+ const entity = select.getEntity(kind, name);
239
267
 
240
268
  if (!entity) {
241
269
  throw new Error(`The entity being edited (${kind}, ${name}) does not have a loaded config.`);
@@ -245,8 +273,8 @@ export function* editEntityRecord(kind, name, recordId, edits, options = {}) {
245
273
  transientEdits = {},
246
274
  mergedEdits = {}
247
275
  } = entity;
248
- const record = yield controls.select(STORE_NAME, 'getRawEntityRecord', kind, name, recordId);
249
- const editedRecord = yield controls.select(STORE_NAME, 'getEditedEntityRecord', kind, name, recordId);
276
+ const record = select.getRawEntityRecord(kind, name, recordId);
277
+ const editedRecord = select.getEditedEntityRecord(kind, name, recordId);
250
278
  const edit = {
251
279
  kind,
252
280
  name,
@@ -264,7 +292,7 @@ export function* editEntityRecord(kind, name, recordId, edits, options = {}) {
264
292
  }, {}),
265
293
  transientEdits
266
294
  };
267
- return {
295
+ dispatch({
268
296
  type: 'EDIT_ENTITY_RECORD',
269
297
  ...edit,
270
298
  meta: {
@@ -276,48 +304,58 @@ export function* editEntityRecord(kind, name, recordId, edits, options = {}) {
276
304
  }, {})
277
305
  }
278
306
  }
279
- };
280
- }
307
+ });
308
+ };
281
309
  /**
282
310
  * Action triggered to undo the last edit to
283
311
  * an entity record, if any.
312
+ *
313
+ * @return {undefined}
284
314
  */
285
315
 
286
- export function* undo() {
287
- const undoEdit = yield controls.select(STORE_NAME, 'getUndoEdit');
316
+ export const undo = () => ({
317
+ select,
318
+ dispatch
319
+ }) => {
320
+ const undoEdit = select.getUndoEdit();
288
321
 
289
322
  if (!undoEdit) {
290
323
  return;
291
324
  }
292
325
 
293
- yield {
326
+ dispatch({
294
327
  type: 'EDIT_ENTITY_RECORD',
295
328
  ...undoEdit,
296
329
  meta: {
297
330
  isUndo: true
298
331
  }
299
- };
300
- }
332
+ });
333
+ };
301
334
  /**
302
335
  * Action triggered to redo the last undoed
303
336
  * edit to an entity record, if any.
337
+ *
338
+ * @return {undefined}
304
339
  */
305
340
 
306
- export function* redo() {
307
- const redoEdit = yield controls.select(STORE_NAME, 'getRedoEdit');
341
+ export const redo = () => ({
342
+ select,
343
+ dispatch
344
+ }) => {
345
+ const redoEdit = select.getRedoEdit();
308
346
 
309
347
  if (!redoEdit) {
310
348
  return;
311
349
  }
312
350
 
313
- yield {
351
+ dispatch({
314
352
  type: 'EDIT_ENTITY_RECORD',
315
353
  ...redoEdit,
316
354
  meta: {
317
355
  isRedo: true
318
356
  }
319
- };
320
- }
357
+ });
358
+ };
321
359
  /**
322
360
  * Forces the creation of a new undo level.
323
361
  *
@@ -339,27 +377,30 @@ export function __unstableCreateUndoLevel() {
339
377
  * @param {boolean} [options.isAutosave=false] Whether this is an autosave.
340
378
  * @param {Function} [options.__unstableFetch] Internal use only. Function to
341
379
  * call instead of `apiFetch()`.
342
- * Must return a control
343
- * descriptor.
380
+ * Must return a promise.
344
381
  */
345
382
 
346
- export function* saveEntityRecord(kind, name, record, {
383
+ export const saveEntityRecord = (kind, name, record, {
347
384
  isAutosave = false,
348
- __unstableFetch = null
349
- } = {}) {
350
- const entities = yield getKindEntities(kind);
385
+ __unstableFetch = apiFetch
386
+ } = {}) => async ({
387
+ select,
388
+ resolveSelect,
389
+ dispatch
390
+ }) => {
391
+ const entities = await dispatch(getKindEntities(kind));
351
392
  const entity = find(entities, {
352
393
  kind,
353
394
  name
354
395
  });
355
396
 
356
- if (!entity) {
397
+ if (!entity || entity !== null && entity !== void 0 && entity.__experimentalNoFetch) {
357
398
  return;
358
399
  }
359
400
 
360
401
  const entityIdKey = entity.key || DEFAULT_ENTITY_KEY;
361
402
  const recordId = record[entityIdKey];
362
- const lock = yield* __unstableAcquireStoreLock(STORE_NAME, ['entities', 'data', kind, name, recordId || uuid()], {
403
+ const lock = await dispatch.__unstableAcquireStoreLock(STORE_NAME, ['entities', 'data', kind, name, recordId || uuid()], {
363
404
  exclusive: true
364
405
  });
365
406
 
@@ -368,8 +409,8 @@ export function* saveEntityRecord(kind, name, record, {
368
409
  // (Function edits that should be evaluated on save to avoid expensive computations on every edit.)
369
410
  for (const [key, value] of Object.entries(record)) {
370
411
  if (typeof value === 'function') {
371
- const evaluatedValue = value(yield controls.select(STORE_NAME, 'getEditedEntityRecord', kind, name, recordId));
372
- yield editEntityRecord(kind, name, recordId, {
412
+ const evaluatedValue = value(select.getEditedEntityRecord(kind, name, recordId));
413
+ dispatch.editEntityRecord(kind, name, recordId, {
373
414
  [key]: evaluatedValue
374
415
  }, {
375
416
  undoIgnore: true
@@ -378,28 +419,28 @@ export function* saveEntityRecord(kind, name, record, {
378
419
  }
379
420
  }
380
421
 
381
- yield {
422
+ dispatch({
382
423
  type: 'SAVE_ENTITY_RECORD_START',
383
424
  kind,
384
425
  name,
385
426
  recordId,
386
427
  isAutosave
387
- };
428
+ });
388
429
  let updatedRecord;
389
430
  let error;
390
431
 
391
432
  try {
392
433
  const path = `${entity.baseURL}${recordId ? '/' + recordId : ''}`;
393
- const persistedRecord = yield controls.select(STORE_NAME, 'getRawEntityRecord', kind, name, recordId);
434
+ const persistedRecord = select.getRawEntityRecord(kind, name, recordId);
394
435
 
395
436
  if (isAutosave) {
396
437
  // Most of this autosave logic is very specific to posts.
397
438
  // This is fine for now as it is the only supported autosave,
398
439
  // but ideally this should all be handled in the back end,
399
440
  // so the client just sends and receives objects.
400
- const currentUser = yield controls.select(STORE_NAME, 'getCurrentUser');
441
+ const currentUser = select.getCurrentUser();
401
442
  const currentUserId = currentUser ? currentUser.id : undefined;
402
- const autosavePost = yield controls.select(STORE_NAME, 'getAutosave', persistedRecord.type, persistedRecord.id, currentUserId); // Autosaves need all expected fields to be present.
443
+ const autosavePost = resolveSelect.getAutosave(persistedRecord.type, persistedRecord.id, currentUserId); // Autosaves need all expected fields to be present.
403
444
  // So we fallback to the previous autosave and then
404
445
  // to the actual persisted entity if the edits don't
405
446
  // have a value.
@@ -410,29 +451,21 @@ export function* saveEntityRecord(kind, name, record, {
410
451
  };
411
452
  data = Object.keys(data).reduce((acc, key) => {
412
453
  if (['title', 'excerpt', 'content'].includes(key)) {
413
- // Edits should be the "raw" attribute values.
414
- acc[key] = get(data[key], 'raw', data[key]);
454
+ acc[key] = data[key];
415
455
  }
416
456
 
417
457
  return acc;
418
458
  }, {
419
459
  status: data.status === 'auto-draft' ? 'draft' : data.status
420
460
  });
421
- const options = {
461
+ updatedRecord = await __unstableFetch({
422
462
  path: `${path}/autosaves`,
423
463
  method: 'POST',
424
464
  data
425
- };
426
-
427
- if (__unstableFetch) {
428
- updatedRecord = yield __unstableAwaitPromise(__unstableFetch(options));
429
- } else {
430
- updatedRecord = yield apiFetch(options);
431
- } // An autosave may be processed by the server as a regular save
465
+ }); // An autosave may be processed by the server as a regular save
432
466
  // when its update is requested by the author and the post had
433
467
  // draft or auto-draft status.
434
468
 
435
-
436
469
  if (persistedRecord.id === updatedRecord.id) {
437
470
  let newRecord = { ...persistedRecord,
438
471
  ...data,
@@ -441,22 +474,21 @@ export function* saveEntityRecord(kind, name, record, {
441
474
  newRecord = Object.keys(newRecord).reduce((acc, key) => {
442
475
  // These properties are persisted in autosaves.
443
476
  if (['title', 'excerpt', 'content'].includes(key)) {
444
- // Edits should be the "raw" attribute values.
445
- acc[key] = get(newRecord[key], 'raw', newRecord[key]);
477
+ acc[key] = newRecord[key];
446
478
  } else if (key === 'status') {
447
479
  // Status is only persisted in autosaves when going from
448
480
  // "auto-draft" to "draft".
449
481
  acc[key] = persistedRecord.status === 'auto-draft' && newRecord.status === 'draft' ? newRecord.status : persistedRecord.status;
450
482
  } else {
451
483
  // These properties are not persisted in autosaves.
452
- acc[key] = get(persistedRecord[key], 'raw', persistedRecord[key]);
484
+ acc[key] = persistedRecord[key];
453
485
  }
454
486
 
455
487
  return acc;
456
488
  }, {});
457
- yield receiveEntityRecords(kind, name, newRecord, undefined, true);
489
+ dispatch.receiveEntityRecords(kind, name, newRecord, undefined, true);
458
490
  } else {
459
- yield receiveAutosaves(persistedRecord.id, updatedRecord);
491
+ dispatch.receiveAutosaves(persistedRecord.id, updatedRecord);
460
492
  }
461
493
  } else {
462
494
  let edits = record;
@@ -467,37 +499,30 @@ export function* saveEntityRecord(kind, name, record, {
467
499
  };
468
500
  }
469
501
 
470
- const options = {
502
+ updatedRecord = await __unstableFetch({
471
503
  path,
472
504
  method: recordId ? 'PUT' : 'POST',
473
505
  data: edits
474
- };
475
-
476
- if (__unstableFetch) {
477
- updatedRecord = yield __unstableAwaitPromise(__unstableFetch(options));
478
- } else {
479
- updatedRecord = yield apiFetch(options);
480
- }
481
-
482
- yield receiveEntityRecords(kind, name, updatedRecord, undefined, true, edits);
506
+ });
507
+ dispatch.receiveEntityRecords(kind, name, updatedRecord, undefined, true, edits);
483
508
  }
484
509
  } catch (_error) {
485
510
  error = _error;
486
511
  }
487
512
 
488
- yield {
513
+ dispatch({
489
514
  type: 'SAVE_ENTITY_RECORD_FINISH',
490
515
  kind,
491
516
  name,
492
517
  recordId,
493
518
  error,
494
519
  isAutosave
495
- };
520
+ });
496
521
  return updatedRecord;
497
522
  } finally {
498
- yield* __unstableReleaseStoreLock(lock);
523
+ dispatch.__unstableReleaseStoreLock(lock);
499
524
  }
500
- }
525
+ };
501
526
  /**
502
527
  * Runs multiple core-data actions at the same time using one API request.
503
528
  *
@@ -521,33 +546,34 @@ export function* saveEntityRecord(kind, name, record, {
521
546
  * values of each function given in `requests`.
522
547
  */
523
548
 
524
- export function* __experimentalBatch(requests) {
549
+ export const __experimentalBatch = requests => async ({
550
+ dispatch
551
+ }) => {
525
552
  const batch = createBatch();
526
- const dispatch = yield getDispatch();
527
553
  const api = {
528
554
  saveEntityRecord(kind, name, record, options) {
529
- return batch.add(add => dispatch(STORE_NAME).saveEntityRecord(kind, name, record, { ...options,
555
+ return batch.add(add => dispatch.saveEntityRecord(kind, name, record, { ...options,
530
556
  __unstableFetch: add
531
557
  }));
532
558
  },
533
559
 
534
560
  saveEditedEntityRecord(kind, name, recordId, options) {
535
- return batch.add(add => dispatch(STORE_NAME).saveEditedEntityRecord(kind, name, recordId, { ...options,
561
+ return batch.add(add => dispatch.saveEditedEntityRecord(kind, name, recordId, { ...options,
536
562
  __unstableFetch: add
537
563
  }));
538
564
  },
539
565
 
540
566
  deleteEntityRecord(kind, name, recordId, query, options) {
541
- return batch.add(add => dispatch(STORE_NAME).deleteEntityRecord(kind, name, recordId, query, { ...options,
567
+ return batch.add(add => dispatch.deleteEntityRecord(kind, name, recordId, query, { ...options,
542
568
  __unstableFetch: add
543
569
  }));
544
570
  }
545
571
 
546
572
  };
547
573
  const resultPromises = requests.map(request => request(api));
548
- const [, ...results] = yield __unstableAwaitPromise(Promise.all([batch.run(), ...resultPromises]));
574
+ const [, ...results] = await Promise.all([batch.run(), ...resultPromises]);
549
575
  return results;
550
- }
576
+ };
551
577
  /**
552
578
  * Action triggered to save an entity record's edits.
553
579
  *
@@ -557,18 +583,32 @@ export function* __experimentalBatch(requests) {
557
583
  * @param {Object} options Saving options.
558
584
  */
559
585
 
560
- export function* saveEditedEntityRecord(kind, name, recordId, options) {
561
- if (!(yield controls.select(STORE_NAME, 'hasEditsForEntityRecord', kind, name, recordId))) {
586
+ export const saveEditedEntityRecord = (kind, name, recordId, options) => async ({
587
+ select,
588
+ dispatch
589
+ }) => {
590
+ if (!select.hasEditsForEntityRecord(kind, name, recordId)) {
562
591
  return;
563
592
  }
564
593
 
565
- const edits = yield controls.select(STORE_NAME, 'getEntityRecordNonTransientEdits', kind, name, recordId);
594
+ const entities = await dispatch(getKindEntities(kind));
595
+ const entity = find(entities, {
596
+ kind,
597
+ name
598
+ });
599
+
600
+ if (!entity) {
601
+ return;
602
+ }
603
+
604
+ const entityIdKey = entity.key || DEFAULT_ENTITY_KEY;
605
+ const edits = select.getEntityRecordNonTransientEdits(kind, name, recordId);
566
606
  const record = {
567
- id: recordId,
607
+ [entityIdKey]: recordId,
568
608
  ...edits
569
609
  };
570
- return yield* saveEntityRecord(kind, name, record, options);
571
- }
610
+ return await dispatch.saveEntityRecord(kind, name, record, options);
611
+ };
572
612
  /**
573
613
  * Action triggered to save only specified properties for the entity.
574
614
  *
@@ -579,12 +619,15 @@ export function* saveEditedEntityRecord(kind, name, recordId, options) {
579
619
  * @param {Object} options Saving options.
580
620
  */
581
621
 
582
- export function* __experimentalSaveSpecifiedEntityEdits(kind, name, recordId, itemsToSave, options) {
583
- if (!(yield controls.select(STORE_NAME, 'hasEditsForEntityRecord', kind, name, recordId))) {
622
+ export const __experimentalSaveSpecifiedEntityEdits = (kind, name, recordId, itemsToSave, options) => async ({
623
+ select,
624
+ dispatch
625
+ }) => {
626
+ if (!select.hasEditsForEntityRecord(kind, name, recordId)) {
584
627
  return;
585
628
  }
586
629
 
587
- const edits = yield controls.select(STORE_NAME, 'getEntityRecordNonTransientEdits', kind, name, recordId);
630
+ const edits = select.getEntityRecordNonTransientEdits(kind, name, recordId);
588
631
  const editsToSave = {};
589
632
 
590
633
  for (const edit in edits) {
@@ -593,8 +636,8 @@ export function* __experimentalSaveSpecifiedEntityEdits(kind, name, recordId, it
593
636
  }
594
637
  }
595
638
 
596
- return yield* saveEntityRecord(kind, name, editsToSave, options);
597
- }
639
+ return await dispatch.saveEntityRecord(kind, name, editsToSave, options);
640
+ };
598
641
  /**
599
642
  * Returns an action object used in signalling that Upload permissions have been received.
600
643
  *