@wordpress/core-data 4.0.1-next.253d9b6e21.0 → 4.0.3

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 (106) hide show
  1. package/README.md +11 -3
  2. package/build/actions.js +124 -117
  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 +24 -18
  7. package/build/entities.js.map +1 -1
  8. package/build/index.js +9 -17
  9. package/build/index.js.map +1 -1
  10. package/build/locks/actions.js +17 -77
  11. package/build/locks/actions.js.map +1 -1
  12. package/build/locks/engine.js +77 -0
  13. package/build/locks/engine.js.map +1 -0
  14. package/build/locks/reducer.js +1 -5
  15. package/build/locks/reducer.js.map +1 -1
  16. package/build/locks/selectors.js +6 -6
  17. package/build/locks/selectors.js.map +1 -1
  18. package/build/queried-data/get-query-parts.js +9 -4
  19. package/build/queried-data/get-query-parts.js.map +1 -1
  20. package/build/queried-data/selectors.js +3 -9
  21. package/build/queried-data/selectors.js.map +1 -1
  22. package/build/reducer.js +1 -4
  23. package/build/reducer.js.map +1 -1
  24. package/build/resolvers.js +120 -91
  25. package/build/resolvers.js.map +1 -1
  26. package/build/selectors.js +31 -11
  27. package/build/selectors.js.map +1 -1
  28. package/build/utils/if-not-resolved.js +6 -21
  29. package/build/utils/if-not-resolved.js.map +1 -1
  30. package/build/utils/index.js +8 -0
  31. package/build/utils/index.js.map +1 -1
  32. package/build/utils/is-raw-attribute.js +19 -0
  33. package/build/utils/is-raw-attribute.js.map +1 -0
  34. package/build-module/actions.js +106 -107
  35. package/build-module/actions.js.map +1 -1
  36. package/build-module/batch/default-processor.js +57 -27
  37. package/build-module/batch/default-processor.js.map +1 -1
  38. package/build-module/entities.js +19 -14
  39. package/build-module/entities.js.map +1 -1
  40. package/build-module/index.js +10 -14
  41. package/build-module/index.js.map +1 -1
  42. package/build-module/locks/actions.js +14 -68
  43. package/build-module/locks/actions.js.map +1 -1
  44. package/build-module/locks/engine.js +66 -0
  45. package/build-module/locks/engine.js.map +1 -0
  46. package/build-module/locks/reducer.js +1 -2
  47. package/build-module/locks/reducer.js.map +1 -1
  48. package/build-module/locks/selectors.js +4 -4
  49. package/build-module/locks/selectors.js.map +1 -1
  50. package/build-module/queried-data/get-query-parts.js +9 -4
  51. package/build-module/queried-data/get-query-parts.js.map +1 -1
  52. package/build-module/queried-data/selectors.js +3 -9
  53. package/build-module/queried-data/selectors.js.map +1 -1
  54. package/build-module/reducer.js +1 -3
  55. package/build-module/reducer.js.map +1 -1
  56. package/build-module/resolvers.js +94 -74
  57. package/build-module/resolvers.js.map +1 -1
  58. package/build-module/selectors.js +30 -10
  59. package/build-module/selectors.js.map +1 -1
  60. package/build-module/utils/if-not-resolved.js +6 -19
  61. package/build-module/utils/if-not-resolved.js.map +1 -1
  62. package/build-module/utils/index.js +1 -0
  63. package/build-module/utils/index.js.map +1 -1
  64. package/build-module/utils/is-raw-attribute.js +12 -0
  65. package/build-module/utils/is-raw-attribute.js.map +1 -0
  66. package/package.json +11 -12
  67. package/src/actions.js +112 -189
  68. package/src/batch/default-processor.js +57 -26
  69. package/src/batch/test/default-processor.js +53 -26
  70. package/src/entities.js +15 -16
  71. package/src/index.js +7 -10
  72. package/src/locks/actions.js +10 -61
  73. package/src/locks/engine.js +43 -0
  74. package/src/locks/reducer.js +1 -3
  75. package/src/locks/selectors.js +4 -4
  76. package/src/locks/test/engine.js +135 -0
  77. package/src/locks/test/reducer.js +1 -1
  78. package/src/locks/test/selectors.js +105 -124
  79. package/src/queried-data/get-query-parts.js +11 -6
  80. package/src/queried-data/selectors.js +2 -9
  81. package/src/queried-data/test/get-query-parts.js +1 -1
  82. package/src/queried-data/test/selectors.js +1 -0
  83. package/src/reducer.js +0 -2
  84. package/src/resolvers.js +86 -106
  85. package/src/selectors.js +113 -40
  86. package/src/test/actions.js +243 -172
  87. package/src/test/entities.js +40 -26
  88. package/src/test/resolvers.js +270 -223
  89. package/src/test/selectors.js +71 -0
  90. package/src/utils/if-not-resolved.js +8 -26
  91. package/src/utils/index.js +1 -0
  92. package/src/utils/is-raw-attribute.js +11 -0
  93. package/src/utils/test/if-not-resolved.js +28 -27
  94. package/src/utils/test/is-raw-attribute.js +22 -0
  95. package/build/controls.js +0 -44
  96. package/build/controls.js.map +0 -1
  97. package/build/locks/index.js +0 -47
  98. package/build/locks/index.js.map +0 -1
  99. package/build-module/controls.js +0 -31
  100. package/build-module/controls.js.map +0 -1
  101. package/build-module/locks/index.js +0 -4
  102. package/build-module/locks/index.js.map +0 -1
  103. package/src/controls.js +0 -31
  104. package/src/locks/index.js +0 -3
  105. package/src/locks/test/actions.js +0 -307
  106. package/src/test/integration.js +0 -264
package/README.md CHANGED
@@ -12,7 +12,7 @@ Install the module
12
12
  npm install @wordpress/core-data --save
13
13
  ```
14
14
 
15
- _This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for ES2015+ such as IE browsers then using [core-js](https://github.com/zloirock/core-js) will add polyfills for these methods._
15
+ _This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for such language features and APIs, you should include [the polyfill shipped in `@wordpress/babel-preset-default`](https://github.com/WordPress/gutenberg/tree/HEAD/packages/babel-preset-default#polyfill) in your code._
16
16
 
17
17
  ## Example
18
18
 
@@ -69,7 +69,7 @@ _Parameters_
69
69
  - _recordId_ `string`: Record ID of the deleted entity.
70
70
  - _query_ `?Object`: Special query parameters for the DELETE API call.
71
71
  - _options_ `[Object]`: Delete options.
72
- - _options.\_\_unstableFetch_ `[Function]`: Internal use only. Function to call instead of `apiFetch()`. Must return a control descriptor.
72
+ - _options.\_\_unstableFetch_ `[Function]`: Internal use only. Function to call instead of `apiFetch()`. Must return a promise.
73
73
 
74
74
  ### editEntityRecord
75
75
 
@@ -214,6 +214,10 @@ _Returns_
214
214
  Action triggered to redo the last undoed
215
215
  edit to an entity record, if any.
216
216
 
217
+ _Returns_
218
+
219
+ - `undefined`:
220
+
217
221
  ### saveEditedEntityRecord
218
222
 
219
223
  Action triggered to save an entity record's edits.
@@ -236,13 +240,17 @@ _Parameters_
236
240
  - _record_ `Object`: Record to be saved.
237
241
  - _options_ `Object`: Saving options.
238
242
  - _options.isAutosave_ `[boolean]`: Whether this is an autosave.
239
- - _options.\_\_unstableFetch_ `[Function]`: Internal use only. Function to call instead of `apiFetch()`. Must return a control descriptor.
243
+ - _options.\_\_unstableFetch_ `[Function]`: Internal use only. Function to call instead of `apiFetch()`. Must return a promise.
240
244
 
241
245
  ### undo
242
246
 
243
247
  Action triggered to undo the last edit to
244
248
  an entity record, if any.
245
249
 
250
+ _Returns_
251
+
252
+ - `undefined`:
253
+
246
254
  <!-- END TOKEN(Autogenerated actions|src/actions.js) -->
247
255
 
248
256
  ## Selectors
package/build/actions.js CHANGED
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
3
5
  Object.defineProperty(exports, "__esModule", {
4
6
  value: true
5
7
  });
@@ -10,26 +12,17 @@ exports.receiveEntityRecords = receiveEntityRecords;
10
12
  exports.receiveCurrentTheme = receiveCurrentTheme;
11
13
  exports.receiveThemeSupports = receiveThemeSupports;
12
14
  exports.receiveEmbedPreview = receiveEmbedPreview;
13
- exports.deleteEntityRecord = deleteEntityRecord;
14
- exports.editEntityRecord = editEntityRecord;
15
- exports.undo = undo;
16
- exports.redo = redo;
17
15
  exports.__unstableCreateUndoLevel = __unstableCreateUndoLevel;
18
- exports.saveEntityRecord = saveEntityRecord;
19
- exports.__experimentalBatch = __experimentalBatch;
20
- exports.saveEditedEntityRecord = saveEditedEntityRecord;
21
- exports.__experimentalSaveSpecifiedEntityEdits = __experimentalSaveSpecifiedEntityEdits;
22
16
  exports.receiveUploadPermissions = receiveUploadPermissions;
23
17
  exports.receiveUserPermission = receiveUserPermission;
24
18
  exports.receiveAutosaves = receiveAutosaves;
19
+ exports.__experimentalSaveSpecifiedEntityEdits = exports.saveEditedEntityRecord = exports.__experimentalBatch = exports.saveEntityRecord = exports.redo = exports.undo = exports.editEntityRecord = exports.deleteEntityRecord = void 0;
25
20
 
26
21
  var _lodash = require("lodash");
27
22
 
28
23
  var _uuid = require("uuid");
29
24
 
30
- var _data = require("@wordpress/data");
31
-
32
- var _dataControls = require("@wordpress/data-controls");
25
+ var _apiFetch = _interopRequireDefault(require("@wordpress/api-fetch"));
33
26
 
34
27
  var _url = require("@wordpress/url");
35
28
 
@@ -37,12 +30,8 @@ var _queriedData = require("./queried-data");
37
30
 
38
31
  var _entities = require("./entities");
39
32
 
40
- var _locks = require("./locks");
41
-
42
33
  var _batch = require("./batch");
43
34
 
44
- var _controls = require("./controls");
45
-
46
35
  var _name = require("./name");
47
36
 
48
37
  /**
@@ -197,14 +186,16 @@ function receiveEmbedPreview(url, preview) {
197
186
  * @param {Object} [options] Delete options.
198
187
  * @param {Function} [options.__unstableFetch] Internal use only. Function to
199
188
  * call instead of `apiFetch()`.
200
- * Must return a control descriptor.
189
+ * Must return a promise.
201
190
  */
202
191
 
203
192
 
204
- function* deleteEntityRecord(kind, name, recordId, query, {
205
- __unstableFetch = null
206
- } = {}) {
207
- const entities = yield (0, _entities.getKindEntities)(kind);
193
+ const deleteEntityRecord = (kind, name, recordId, query, {
194
+ __unstableFetch = _apiFetch.default
195
+ } = {}) => async ({
196
+ dispatch
197
+ }) => {
198
+ const entities = await dispatch((0, _entities.getKindEntities)(kind));
208
199
  const entity = (0, _lodash.find)(entities, {
209
200
  kind,
210
201
  name
@@ -212,21 +203,21 @@ function* deleteEntityRecord(kind, name, recordId, query, {
212
203
  let error;
213
204
  let deletedRecord = false;
214
205
 
215
- if (!entity) {
206
+ if (!entity || entity !== null && entity !== void 0 && entity.__experimentalNoFetch) {
216
207
  return;
217
208
  }
218
209
 
219
- const lock = yield* (0, _locks.__unstableAcquireStoreLock)(_name.STORE_NAME, ['entities', 'data', kind, name, recordId], {
210
+ const lock = await dispatch.__unstableAcquireStoreLock(_name.STORE_NAME, ['entities', 'data', kind, name, recordId], {
220
211
  exclusive: true
221
212
  });
222
213
 
223
214
  try {
224
- yield {
215
+ dispatch({
225
216
  type: 'DELETE_ENTITY_RECORD_START',
226
217
  kind,
227
218
  name,
228
219
  recordId
229
- };
220
+ });
230
221
 
231
222
  try {
232
223
  let path = `${entity.baseURL}/${recordId}`;
@@ -235,34 +226,27 @@ function* deleteEntityRecord(kind, name, recordId, query, {
235
226
  path = (0, _url.addQueryArgs)(path, query);
236
227
  }
237
228
 
238
- const options = {
229
+ deletedRecord = await __unstableFetch({
239
230
  path,
240
231
  method: 'DELETE'
241
- };
242
-
243
- if (__unstableFetch) {
244
- deletedRecord = yield (0, _dataControls.__unstableAwaitPromise)(__unstableFetch(options));
245
- } else {
246
- deletedRecord = yield (0, _dataControls.apiFetch)(options);
247
- }
248
-
249
- yield (0, _queriedData.removeItems)(kind, name, recordId, true);
232
+ });
233
+ await dispatch((0, _queriedData.removeItems)(kind, name, recordId, true));
250
234
  } catch (_error) {
251
235
  error = _error;
252
236
  }
253
237
 
254
- yield {
238
+ dispatch({
255
239
  type: 'DELETE_ENTITY_RECORD_FINISH',
256
240
  kind,
257
241
  name,
258
242
  recordId,
259
243
  error
260
- };
244
+ });
261
245
  return deletedRecord;
262
246
  } finally {
263
- yield* (0, _locks.__unstableReleaseStoreLock)(lock);
247
+ dispatch.__unstableReleaseStoreLock(lock);
264
248
  }
265
- }
249
+ };
266
250
  /**
267
251
  * Returns an action object that triggers an
268
252
  * edit to an entity record.
@@ -278,8 +262,13 @@ function* deleteEntityRecord(kind, name, recordId, query, {
278
262
  */
279
263
 
280
264
 
281
- function* editEntityRecord(kind, name, recordId, edits, options = {}) {
282
- const entity = yield _data.controls.select(_name.STORE_NAME, 'getEntity', kind, name);
265
+ exports.deleteEntityRecord = deleteEntityRecord;
266
+
267
+ const editEntityRecord = (kind, name, recordId, edits, options = {}) => ({
268
+ select,
269
+ dispatch
270
+ }) => {
271
+ const entity = select.getEntity(kind, name);
283
272
 
284
273
  if (!entity) {
285
274
  throw new Error(`The entity being edited (${kind}, ${name}) does not have a loaded config.`);
@@ -289,8 +278,8 @@ function* editEntityRecord(kind, name, recordId, edits, options = {}) {
289
278
  transientEdits = {},
290
279
  mergedEdits = {}
291
280
  } = entity;
292
- const record = yield _data.controls.select(_name.STORE_NAME, 'getRawEntityRecord', kind, name, recordId);
293
- const editedRecord = yield _data.controls.select(_name.STORE_NAME, 'getEditedEntityRecord', kind, name, recordId);
281
+ const record = select.getRawEntityRecord(kind, name, recordId);
282
+ const editedRecord = select.getEditedEntityRecord(kind, name, recordId);
294
283
  const edit = {
295
284
  kind,
296
285
  name,
@@ -308,7 +297,7 @@ function* editEntityRecord(kind, name, recordId, edits, options = {}) {
308
297
  }, {}),
309
298
  transientEdits
310
299
  };
311
- return {
300
+ dispatch({
312
301
  type: 'EDIT_ENTITY_RECORD',
313
302
  ...edit,
314
303
  meta: {
@@ -320,50 +309,64 @@ function* editEntityRecord(kind, name, recordId, edits, options = {}) {
320
309
  }, {})
321
310
  }
322
311
  }
323
- };
324
- }
312
+ });
313
+ };
325
314
  /**
326
315
  * Action triggered to undo the last edit to
327
316
  * an entity record, if any.
317
+ *
318
+ * @return {undefined}
328
319
  */
329
320
 
330
321
 
331
- function* undo() {
332
- const undoEdit = yield _data.controls.select(_name.STORE_NAME, 'getUndoEdit');
322
+ exports.editEntityRecord = editEntityRecord;
323
+
324
+ const undo = () => ({
325
+ select,
326
+ dispatch
327
+ }) => {
328
+ const undoEdit = select.getUndoEdit();
333
329
 
334
330
  if (!undoEdit) {
335
331
  return;
336
332
  }
337
333
 
338
- yield {
334
+ dispatch({
339
335
  type: 'EDIT_ENTITY_RECORD',
340
336
  ...undoEdit,
341
337
  meta: {
342
338
  isUndo: true
343
339
  }
344
- };
345
- }
340
+ });
341
+ };
346
342
  /**
347
343
  * Action triggered to redo the last undoed
348
344
  * edit to an entity record, if any.
345
+ *
346
+ * @return {undefined}
349
347
  */
350
348
 
351
349
 
352
- function* redo() {
353
- const redoEdit = yield _data.controls.select(_name.STORE_NAME, 'getRedoEdit');
350
+ exports.undo = undo;
351
+
352
+ const redo = () => ({
353
+ select,
354
+ dispatch
355
+ }) => {
356
+ const redoEdit = select.getRedoEdit();
354
357
 
355
358
  if (!redoEdit) {
356
359
  return;
357
360
  }
358
361
 
359
- yield {
362
+ dispatch({
360
363
  type: 'EDIT_ENTITY_RECORD',
361
364
  ...redoEdit,
362
365
  meta: {
363
366
  isRedo: true
364
367
  }
365
- };
366
- }
368
+ });
369
+ };
367
370
  /**
368
371
  * Forces the creation of a new undo level.
369
372
  *
@@ -371,6 +374,8 @@ function* redo() {
371
374
  */
372
375
 
373
376
 
377
+ exports.redo = redo;
378
+
374
379
  function __unstableCreateUndoLevel() {
375
380
  return {
376
381
  type: 'CREATE_UNDO_LEVEL'
@@ -386,28 +391,31 @@ function __unstableCreateUndoLevel() {
386
391
  * @param {boolean} [options.isAutosave=false] Whether this is an autosave.
387
392
  * @param {Function} [options.__unstableFetch] Internal use only. Function to
388
393
  * call instead of `apiFetch()`.
389
- * Must return a control
390
- * descriptor.
394
+ * Must return a promise.
391
395
  */
392
396
 
393
397
 
394
- function* saveEntityRecord(kind, name, record, {
398
+ const saveEntityRecord = (kind, name, record, {
395
399
  isAutosave = false,
396
- __unstableFetch = null
397
- } = {}) {
398
- const entities = yield (0, _entities.getKindEntities)(kind);
400
+ __unstableFetch = _apiFetch.default
401
+ } = {}) => async ({
402
+ select,
403
+ resolveSelect,
404
+ dispatch
405
+ }) => {
406
+ const entities = await dispatch((0, _entities.getKindEntities)(kind));
399
407
  const entity = (0, _lodash.find)(entities, {
400
408
  kind,
401
409
  name
402
410
  });
403
411
 
404
- if (!entity) {
412
+ if (!entity || entity !== null && entity !== void 0 && entity.__experimentalNoFetch) {
405
413
  return;
406
414
  }
407
415
 
408
416
  const entityIdKey = entity.key || _entities.DEFAULT_ENTITY_KEY;
409
417
  const recordId = record[entityIdKey];
410
- const lock = yield* (0, _locks.__unstableAcquireStoreLock)(_name.STORE_NAME, ['entities', 'data', kind, name, recordId || (0, _uuid.v4)()], {
418
+ const lock = await dispatch.__unstableAcquireStoreLock(_name.STORE_NAME, ['entities', 'data', kind, name, recordId || (0, _uuid.v4)()], {
411
419
  exclusive: true
412
420
  });
413
421
 
@@ -416,8 +424,8 @@ function* saveEntityRecord(kind, name, record, {
416
424
  // (Function edits that should be evaluated on save to avoid expensive computations on every edit.)
417
425
  for (const [key, value] of Object.entries(record)) {
418
426
  if (typeof value === 'function') {
419
- const evaluatedValue = value(yield _data.controls.select(_name.STORE_NAME, 'getEditedEntityRecord', kind, name, recordId));
420
- yield editEntityRecord(kind, name, recordId, {
427
+ const evaluatedValue = value(select.getEditedEntityRecord(kind, name, recordId));
428
+ dispatch.editEntityRecord(kind, name, recordId, {
421
429
  [key]: evaluatedValue
422
430
  }, {
423
431
  undoIgnore: true
@@ -426,28 +434,28 @@ function* saveEntityRecord(kind, name, record, {
426
434
  }
427
435
  }
428
436
 
429
- yield {
437
+ dispatch({
430
438
  type: 'SAVE_ENTITY_RECORD_START',
431
439
  kind,
432
440
  name,
433
441
  recordId,
434
442
  isAutosave
435
- };
443
+ });
436
444
  let updatedRecord;
437
445
  let error;
438
446
 
439
447
  try {
440
448
  const path = `${entity.baseURL}${recordId ? '/' + recordId : ''}`;
441
- const persistedRecord = yield _data.controls.select(_name.STORE_NAME, 'getRawEntityRecord', kind, name, recordId);
449
+ const persistedRecord = select.getRawEntityRecord(kind, name, recordId);
442
450
 
443
451
  if (isAutosave) {
444
452
  // Most of this autosave logic is very specific to posts.
445
453
  // This is fine for now as it is the only supported autosave,
446
454
  // but ideally this should all be handled in the back end,
447
455
  // so the client just sends and receives objects.
448
- const currentUser = yield _data.controls.select(_name.STORE_NAME, 'getCurrentUser');
456
+ const currentUser = select.getCurrentUser();
449
457
  const currentUserId = currentUser ? currentUser.id : undefined;
450
- const autosavePost = yield _data.controls.select(_name.STORE_NAME, 'getAutosave', persistedRecord.type, persistedRecord.id, currentUserId); // Autosaves need all expected fields to be present.
458
+ const autosavePost = resolveSelect.getAutosave(persistedRecord.type, persistedRecord.id, currentUserId); // Autosaves need all expected fields to be present.
451
459
  // So we fallback to the previous autosave and then
452
460
  // to the actual persisted entity if the edits don't
453
461
  // have a value.
@@ -458,29 +466,21 @@ function* saveEntityRecord(kind, name, record, {
458
466
  };
459
467
  data = Object.keys(data).reduce((acc, key) => {
460
468
  if (['title', 'excerpt', 'content'].includes(key)) {
461
- // Edits should be the "raw" attribute values.
462
- acc[key] = (0, _lodash.get)(data[key], 'raw', data[key]);
469
+ acc[key] = data[key];
463
470
  }
464
471
 
465
472
  return acc;
466
473
  }, {
467
474
  status: data.status === 'auto-draft' ? 'draft' : data.status
468
475
  });
469
- const options = {
476
+ updatedRecord = await __unstableFetch({
470
477
  path: `${path}/autosaves`,
471
478
  method: 'POST',
472
479
  data
473
- };
474
-
475
- if (__unstableFetch) {
476
- updatedRecord = yield (0, _dataControls.__unstableAwaitPromise)(__unstableFetch(options));
477
- } else {
478
- updatedRecord = yield (0, _dataControls.apiFetch)(options);
479
- } // An autosave may be processed by the server as a regular save
480
+ }); // An autosave may be processed by the server as a regular save
480
481
  // when its update is requested by the author and the post had
481
482
  // draft or auto-draft status.
482
483
 
483
-
484
484
  if (persistedRecord.id === updatedRecord.id) {
485
485
  let newRecord = { ...persistedRecord,
486
486
  ...data,
@@ -489,22 +489,21 @@ function* saveEntityRecord(kind, name, record, {
489
489
  newRecord = Object.keys(newRecord).reduce((acc, key) => {
490
490
  // These properties are persisted in autosaves.
491
491
  if (['title', 'excerpt', 'content'].includes(key)) {
492
- // Edits should be the "raw" attribute values.
493
- acc[key] = (0, _lodash.get)(newRecord[key], 'raw', newRecord[key]);
492
+ acc[key] = newRecord[key];
494
493
  } else if (key === 'status') {
495
494
  // Status is only persisted in autosaves when going from
496
495
  // "auto-draft" to "draft".
497
496
  acc[key] = persistedRecord.status === 'auto-draft' && newRecord.status === 'draft' ? newRecord.status : persistedRecord.status;
498
497
  } else {
499
498
  // These properties are not persisted in autosaves.
500
- acc[key] = (0, _lodash.get)(persistedRecord[key], 'raw', persistedRecord[key]);
499
+ acc[key] = persistedRecord[key];
501
500
  }
502
501
 
503
502
  return acc;
504
503
  }, {});
505
- yield receiveEntityRecords(kind, name, newRecord, undefined, true);
504
+ dispatch.receiveEntityRecords(kind, name, newRecord, undefined, true);
506
505
  } else {
507
- yield receiveAutosaves(persistedRecord.id, updatedRecord);
506
+ dispatch.receiveAutosaves(persistedRecord.id, updatedRecord);
508
507
  }
509
508
  } else {
510
509
  let edits = record;
@@ -515,37 +514,30 @@ function* saveEntityRecord(kind, name, record, {
515
514
  };
516
515
  }
517
516
 
518
- const options = {
517
+ updatedRecord = await __unstableFetch({
519
518
  path,
520
519
  method: recordId ? 'PUT' : 'POST',
521
520
  data: edits
522
- };
523
-
524
- if (__unstableFetch) {
525
- updatedRecord = yield (0, _dataControls.__unstableAwaitPromise)(__unstableFetch(options));
526
- } else {
527
- updatedRecord = yield (0, _dataControls.apiFetch)(options);
528
- }
529
-
530
- yield receiveEntityRecords(kind, name, updatedRecord, undefined, true, edits);
521
+ });
522
+ dispatch.receiveEntityRecords(kind, name, updatedRecord, undefined, true, edits);
531
523
  }
532
524
  } catch (_error) {
533
525
  error = _error;
534
526
  }
535
527
 
536
- yield {
528
+ dispatch({
537
529
  type: 'SAVE_ENTITY_RECORD_FINISH',
538
530
  kind,
539
531
  name,
540
532
  recordId,
541
533
  error,
542
534
  isAutosave
543
- };
535
+ });
544
536
  return updatedRecord;
545
537
  } finally {
546
- yield* (0, _locks.__unstableReleaseStoreLock)(lock);
538
+ dispatch.__unstableReleaseStoreLock(lock);
547
539
  }
548
- }
540
+ };
549
541
  /**
550
542
  * Runs multiple core-data actions at the same time using one API request.
551
543
  *
@@ -570,33 +562,36 @@ function* saveEntityRecord(kind, name, record, {
570
562
  */
571
563
 
572
564
 
573
- function* __experimentalBatch(requests) {
565
+ exports.saveEntityRecord = saveEntityRecord;
566
+
567
+ const __experimentalBatch = requests => async ({
568
+ dispatch
569
+ }) => {
574
570
  const batch = (0, _batch.createBatch)();
575
- const dispatch = yield (0, _controls.getDispatch)();
576
571
  const api = {
577
572
  saveEntityRecord(kind, name, record, options) {
578
- return batch.add(add => dispatch(_name.STORE_NAME).saveEntityRecord(kind, name, record, { ...options,
573
+ return batch.add(add => dispatch.saveEntityRecord(kind, name, record, { ...options,
579
574
  __unstableFetch: add
580
575
  }));
581
576
  },
582
577
 
583
578
  saveEditedEntityRecord(kind, name, recordId, options) {
584
- return batch.add(add => dispatch(_name.STORE_NAME).saveEditedEntityRecord(kind, name, recordId, { ...options,
579
+ return batch.add(add => dispatch.saveEditedEntityRecord(kind, name, recordId, { ...options,
585
580
  __unstableFetch: add
586
581
  }));
587
582
  },
588
583
 
589
584
  deleteEntityRecord(kind, name, recordId, query, options) {
590
- return batch.add(add => dispatch(_name.STORE_NAME).deleteEntityRecord(kind, name, recordId, query, { ...options,
585
+ return batch.add(add => dispatch.deleteEntityRecord(kind, name, recordId, query, { ...options,
591
586
  __unstableFetch: add
592
587
  }));
593
588
  }
594
589
 
595
590
  };
596
591
  const resultPromises = requests.map(request => request(api));
597
- const [, ...results] = yield (0, _dataControls.__unstableAwaitPromise)(Promise.all([batch.run(), ...resultPromises]));
592
+ const [, ...results] = await Promise.all([batch.run(), ...resultPromises]);
598
593
  return results;
599
- }
594
+ };
600
595
  /**
601
596
  * Action triggered to save an entity record's edits.
602
597
  *
@@ -607,18 +602,23 @@ function* __experimentalBatch(requests) {
607
602
  */
608
603
 
609
604
 
610
- function* saveEditedEntityRecord(kind, name, recordId, options) {
611
- if (!(yield _data.controls.select(_name.STORE_NAME, 'hasEditsForEntityRecord', kind, name, recordId))) {
605
+ exports.__experimentalBatch = __experimentalBatch;
606
+
607
+ const saveEditedEntityRecord = (kind, name, recordId, options) => async ({
608
+ select,
609
+ dispatch
610
+ }) => {
611
+ if (!select.hasEditsForEntityRecord(kind, name, recordId)) {
612
612
  return;
613
613
  }
614
614
 
615
- const edits = yield _data.controls.select(_name.STORE_NAME, 'getEntityRecordNonTransientEdits', kind, name, recordId);
615
+ const edits = select.getEntityRecordNonTransientEdits(kind, name, recordId);
616
616
  const record = {
617
617
  id: recordId,
618
618
  ...edits
619
619
  };
620
- return yield* saveEntityRecord(kind, name, record, options);
621
- }
620
+ return await dispatch.saveEntityRecord(kind, name, record, options);
621
+ };
622
622
  /**
623
623
  * Action triggered to save only specified properties for the entity.
624
624
  *
@@ -630,12 +630,17 @@ function* saveEditedEntityRecord(kind, name, recordId, options) {
630
630
  */
631
631
 
632
632
 
633
- function* __experimentalSaveSpecifiedEntityEdits(kind, name, recordId, itemsToSave, options) {
634
- if (!(yield _data.controls.select(_name.STORE_NAME, 'hasEditsForEntityRecord', kind, name, recordId))) {
633
+ exports.saveEditedEntityRecord = saveEditedEntityRecord;
634
+
635
+ const __experimentalSaveSpecifiedEntityEdits = (kind, name, recordId, itemsToSave, options) => async ({
636
+ select,
637
+ dispatch
638
+ }) => {
639
+ if (!select.hasEditsForEntityRecord(kind, name, recordId)) {
635
640
  return;
636
641
  }
637
642
 
638
- const edits = yield _data.controls.select(_name.STORE_NAME, 'getEntityRecordNonTransientEdits', kind, name, recordId);
643
+ const edits = select.getEntityRecordNonTransientEdits(kind, name, recordId);
639
644
  const editsToSave = {};
640
645
 
641
646
  for (const edit in edits) {
@@ -644,8 +649,8 @@ function* __experimentalSaveSpecifiedEntityEdits(kind, name, recordId, itemsToSa
644
649
  }
645
650
  }
646
651
 
647
- return yield* saveEntityRecord(kind, name, editsToSave, options);
648
- }
652
+ return await dispatch.saveEntityRecord(kind, name, editsToSave, options);
653
+ };
649
654
  /**
650
655
  * Returns an action object used in signalling that Upload permissions have been received.
651
656
  *
@@ -655,6 +660,8 @@ function* __experimentalSaveSpecifiedEntityEdits(kind, name, recordId, itemsToSa
655
660
  */
656
661
 
657
662
 
663
+ exports.__experimentalSaveSpecifiedEntityEdits = __experimentalSaveSpecifiedEntityEdits;
664
+
658
665
  function receiveUploadPermissions(hasUploadPermissions) {
659
666
  return {
660
667
  type: 'RECEIVE_USER_PERMISSION',