@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.
- package/README.md +11 -3
- package/build/actions.js +124 -117
- package/build/actions.js.map +1 -1
- package/build/batch/default-processor.js +58 -27
- package/build/batch/default-processor.js.map +1 -1
- package/build/entities.js +24 -18
- package/build/entities.js.map +1 -1
- package/build/index.js +9 -17
- package/build/index.js.map +1 -1
- package/build/locks/actions.js +17 -77
- package/build/locks/actions.js.map +1 -1
- package/build/locks/engine.js +77 -0
- package/build/locks/engine.js.map +1 -0
- package/build/locks/reducer.js +1 -5
- package/build/locks/reducer.js.map +1 -1
- package/build/locks/selectors.js +6 -6
- package/build/locks/selectors.js.map +1 -1
- package/build/queried-data/get-query-parts.js +9 -4
- package/build/queried-data/get-query-parts.js.map +1 -1
- package/build/queried-data/selectors.js +3 -9
- package/build/queried-data/selectors.js.map +1 -1
- package/build/reducer.js +1 -4
- package/build/reducer.js.map +1 -1
- package/build/resolvers.js +120 -91
- package/build/resolvers.js.map +1 -1
- package/build/selectors.js +31 -11
- package/build/selectors.js.map +1 -1
- package/build/utils/if-not-resolved.js +6 -21
- package/build/utils/if-not-resolved.js.map +1 -1
- package/build/utils/index.js +8 -0
- package/build/utils/index.js.map +1 -1
- package/build/utils/is-raw-attribute.js +19 -0
- package/build/utils/is-raw-attribute.js.map +1 -0
- package/build-module/actions.js +106 -107
- package/build-module/actions.js.map +1 -1
- package/build-module/batch/default-processor.js +57 -27
- package/build-module/batch/default-processor.js.map +1 -1
- package/build-module/entities.js +19 -14
- package/build-module/entities.js.map +1 -1
- package/build-module/index.js +10 -14
- package/build-module/index.js.map +1 -1
- package/build-module/locks/actions.js +14 -68
- package/build-module/locks/actions.js.map +1 -1
- package/build-module/locks/engine.js +66 -0
- package/build-module/locks/engine.js.map +1 -0
- package/build-module/locks/reducer.js +1 -2
- package/build-module/locks/reducer.js.map +1 -1
- package/build-module/locks/selectors.js +4 -4
- package/build-module/locks/selectors.js.map +1 -1
- package/build-module/queried-data/get-query-parts.js +9 -4
- package/build-module/queried-data/get-query-parts.js.map +1 -1
- package/build-module/queried-data/selectors.js +3 -9
- package/build-module/queried-data/selectors.js.map +1 -1
- package/build-module/reducer.js +1 -3
- package/build-module/reducer.js.map +1 -1
- package/build-module/resolvers.js +94 -74
- package/build-module/resolvers.js.map +1 -1
- package/build-module/selectors.js +30 -10
- package/build-module/selectors.js.map +1 -1
- package/build-module/utils/if-not-resolved.js +6 -19
- package/build-module/utils/if-not-resolved.js.map +1 -1
- package/build-module/utils/index.js +1 -0
- package/build-module/utils/index.js.map +1 -1
- package/build-module/utils/is-raw-attribute.js +12 -0
- package/build-module/utils/is-raw-attribute.js.map +1 -0
- package/package.json +11 -12
- package/src/actions.js +112 -189
- package/src/batch/default-processor.js +57 -26
- package/src/batch/test/default-processor.js +53 -26
- package/src/entities.js +15 -16
- package/src/index.js +7 -10
- package/src/locks/actions.js +10 -61
- package/src/locks/engine.js +43 -0
- package/src/locks/reducer.js +1 -3
- package/src/locks/selectors.js +4 -4
- package/src/locks/test/engine.js +135 -0
- package/src/locks/test/reducer.js +1 -1
- package/src/locks/test/selectors.js +105 -124
- package/src/queried-data/get-query-parts.js +11 -6
- package/src/queried-data/selectors.js +2 -9
- package/src/queried-data/test/get-query-parts.js +1 -1
- package/src/queried-data/test/selectors.js +1 -0
- package/src/reducer.js +0 -2
- package/src/resolvers.js +86 -106
- package/src/selectors.js +113 -40
- package/src/test/actions.js +243 -172
- package/src/test/entities.js +40 -26
- package/src/test/resolvers.js +270 -223
- package/src/test/selectors.js +71 -0
- package/src/utils/if-not-resolved.js +8 -26
- package/src/utils/index.js +1 -0
- package/src/utils/is-raw-attribute.js +11 -0
- package/src/utils/test/if-not-resolved.js +28 -27
- package/src/utils/test/is-raw-attribute.js +22 -0
- package/build/controls.js +0 -44
- package/build/controls.js.map +0 -1
- package/build/locks/index.js +0 -47
- package/build/locks/index.js.map +0 -1
- package/build-module/controls.js +0 -31
- package/build-module/controls.js.map +0 -1
- package/build-module/locks/index.js +0 -4
- package/build-module/locks/index.js.map +0 -1
- package/src/controls.js +0 -31
- package/src/locks/index.js +0 -3
- package/src/locks/test/actions.js +0 -307
- package/src/test/integration.js +0 -264
package/src/actions.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { castArray,
|
|
4
|
+
import { castArray, isEqual, find } from 'lodash';
|
|
5
5
|
import { v4 as uuid } from 'uuid';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* WordPress dependencies
|
|
9
9
|
*/
|
|
10
|
-
import
|
|
11
|
-
import { apiFetch, __unstableAwaitPromise } from '@wordpress/data-controls';
|
|
10
|
+
import apiFetch from '@wordpress/api-fetch';
|
|
12
11
|
import { addQueryArgs } from '@wordpress/url';
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -16,12 +15,7 @@ import { addQueryArgs } from '@wordpress/url';
|
|
|
16
15
|
*/
|
|
17
16
|
import { receiveItems, removeItems, receiveQueriedItems } from './queried-data';
|
|
18
17
|
import { getKindEntities, DEFAULT_ENTITY_KEY } from './entities';
|
|
19
|
-
import {
|
|
20
|
-
__unstableAcquireStoreLock,
|
|
21
|
-
__unstableReleaseStoreLock,
|
|
22
|
-
} from './locks';
|
|
23
18
|
import { createBatch } from './batch';
|
|
24
|
-
import { getDispatch } from './controls';
|
|
25
19
|
import { STORE_NAME } from './name';
|
|
26
20
|
|
|
27
21
|
/**
|
|
@@ -165,35 +159,36 @@ export function receiveEmbedPreview( url, preview ) {
|
|
|
165
159
|
* @param {Object} [options] Delete options.
|
|
166
160
|
* @param {Function} [options.__unstableFetch] Internal use only. Function to
|
|
167
161
|
* call instead of `apiFetch()`.
|
|
168
|
-
* Must return a
|
|
162
|
+
* Must return a promise.
|
|
169
163
|
*/
|
|
170
|
-
export
|
|
164
|
+
export const deleteEntityRecord = (
|
|
171
165
|
kind,
|
|
172
166
|
name,
|
|
173
167
|
recordId,
|
|
174
168
|
query,
|
|
175
|
-
{ __unstableFetch =
|
|
176
|
-
) {
|
|
177
|
-
const entities =
|
|
169
|
+
{ __unstableFetch = apiFetch } = {}
|
|
170
|
+
) => async ( { dispatch } ) => {
|
|
171
|
+
const entities = await dispatch( getKindEntities( kind ) );
|
|
178
172
|
const entity = find( entities, { kind, name } );
|
|
179
173
|
let error;
|
|
180
174
|
let deletedRecord = false;
|
|
181
|
-
if ( ! entity ) {
|
|
175
|
+
if ( ! entity || entity?.__experimentalNoFetch ) {
|
|
182
176
|
return;
|
|
183
177
|
}
|
|
184
178
|
|
|
185
|
-
const lock =
|
|
179
|
+
const lock = await dispatch.__unstableAcquireStoreLock(
|
|
186
180
|
STORE_NAME,
|
|
187
181
|
[ 'entities', 'data', kind, name, recordId ],
|
|
188
182
|
{ exclusive: true }
|
|
189
183
|
);
|
|
184
|
+
|
|
190
185
|
try {
|
|
191
|
-
|
|
186
|
+
dispatch( {
|
|
192
187
|
type: 'DELETE_ENTITY_RECORD_START',
|
|
193
188
|
kind,
|
|
194
189
|
name,
|
|
195
190
|
recordId,
|
|
196
|
-
};
|
|
191
|
+
} );
|
|
197
192
|
|
|
198
193
|
try {
|
|
199
194
|
let path = `${ entity.baseURL }/${ recordId }`;
|
|
@@ -202,36 +197,29 @@ export function* deleteEntityRecord(
|
|
|
202
197
|
path = addQueryArgs( path, query );
|
|
203
198
|
}
|
|
204
199
|
|
|
205
|
-
|
|
200
|
+
deletedRecord = await __unstableFetch( {
|
|
206
201
|
path,
|
|
207
202
|
method: 'DELETE',
|
|
208
|
-
};
|
|
209
|
-
if ( __unstableFetch ) {
|
|
210
|
-
deletedRecord = yield __unstableAwaitPromise(
|
|
211
|
-
__unstableFetch( options )
|
|
212
|
-
);
|
|
213
|
-
} else {
|
|
214
|
-
deletedRecord = yield apiFetch( options );
|
|
215
|
-
}
|
|
203
|
+
} );
|
|
216
204
|
|
|
217
|
-
|
|
205
|
+
await dispatch( removeItems( kind, name, recordId, true ) );
|
|
218
206
|
} catch ( _error ) {
|
|
219
207
|
error = _error;
|
|
220
208
|
}
|
|
221
209
|
|
|
222
|
-
|
|
210
|
+
dispatch( {
|
|
223
211
|
type: 'DELETE_ENTITY_RECORD_FINISH',
|
|
224
212
|
kind,
|
|
225
213
|
name,
|
|
226
214
|
recordId,
|
|
227
215
|
error,
|
|
228
|
-
};
|
|
216
|
+
} );
|
|
229
217
|
|
|
230
218
|
return deletedRecord;
|
|
231
219
|
} finally {
|
|
232
|
-
|
|
220
|
+
dispatch.__unstableReleaseStoreLock( lock );
|
|
233
221
|
}
|
|
234
|
-
}
|
|
222
|
+
};
|
|
235
223
|
|
|
236
224
|
/**
|
|
237
225
|
* Returns an action object that triggers an
|
|
@@ -246,28 +234,22 @@ export function* deleteEntityRecord(
|
|
|
246
234
|
*
|
|
247
235
|
* @return {Object} Action object.
|
|
248
236
|
*/
|
|
249
|
-
export
|
|
250
|
-
|
|
237
|
+
export const editEntityRecord = (
|
|
238
|
+
kind,
|
|
239
|
+
name,
|
|
240
|
+
recordId,
|
|
241
|
+
edits,
|
|
242
|
+
options = {}
|
|
243
|
+
) => ( { select, dispatch } ) => {
|
|
244
|
+
const entity = select.getEntity( kind, name );
|
|
251
245
|
if ( ! entity ) {
|
|
252
246
|
throw new Error(
|
|
253
247
|
`The entity being edited (${ kind }, ${ name }) does not have a loaded config.`
|
|
254
248
|
);
|
|
255
249
|
}
|
|
256
250
|
const { transientEdits = {}, mergedEdits = {} } = entity;
|
|
257
|
-
const record =
|
|
258
|
-
|
|
259
|
-
'getRawEntityRecord',
|
|
260
|
-
kind,
|
|
261
|
-
name,
|
|
262
|
-
recordId
|
|
263
|
-
);
|
|
264
|
-
const editedRecord = yield controls.select(
|
|
265
|
-
STORE_NAME,
|
|
266
|
-
'getEditedEntityRecord',
|
|
267
|
-
kind,
|
|
268
|
-
name,
|
|
269
|
-
recordId
|
|
270
|
-
);
|
|
251
|
+
const record = select.getRawEntityRecord( kind, name, recordId );
|
|
252
|
+
const editedRecord = select.getEditedEntityRecord( kind, name, recordId );
|
|
271
253
|
|
|
272
254
|
const edit = {
|
|
273
255
|
kind,
|
|
@@ -286,7 +268,7 @@ export function* editEntityRecord( kind, name, recordId, edits, options = {} ) {
|
|
|
286
268
|
}, {} ),
|
|
287
269
|
transientEdits,
|
|
288
270
|
};
|
|
289
|
-
|
|
271
|
+
dispatch( {
|
|
290
272
|
type: 'EDIT_ENTITY_RECORD',
|
|
291
273
|
...edit,
|
|
292
274
|
meta: {
|
|
@@ -299,44 +281,44 @@ export function* editEntityRecord( kind, name, recordId, edits, options = {} ) {
|
|
|
299
281
|
}, {} ),
|
|
300
282
|
},
|
|
301
283
|
},
|
|
302
|
-
};
|
|
303
|
-
}
|
|
284
|
+
} );
|
|
285
|
+
};
|
|
304
286
|
|
|
305
287
|
/**
|
|
306
288
|
* Action triggered to undo the last edit to
|
|
307
289
|
* an entity record, if any.
|
|
290
|
+
*
|
|
291
|
+
* @return {undefined}
|
|
308
292
|
*/
|
|
309
|
-
export
|
|
310
|
-
const undoEdit =
|
|
293
|
+
export const undo = () => ( { select, dispatch } ) => {
|
|
294
|
+
const undoEdit = select.getUndoEdit();
|
|
311
295
|
if ( ! undoEdit ) {
|
|
312
296
|
return;
|
|
313
297
|
}
|
|
314
|
-
|
|
298
|
+
dispatch( {
|
|
315
299
|
type: 'EDIT_ENTITY_RECORD',
|
|
316
300
|
...undoEdit,
|
|
317
|
-
meta: {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
};
|
|
321
|
-
}
|
|
301
|
+
meta: { isUndo: true },
|
|
302
|
+
} );
|
|
303
|
+
};
|
|
322
304
|
|
|
323
305
|
/**
|
|
324
306
|
* Action triggered to redo the last undoed
|
|
325
307
|
* edit to an entity record, if any.
|
|
308
|
+
*
|
|
309
|
+
* @return {undefined}
|
|
326
310
|
*/
|
|
327
|
-
export
|
|
328
|
-
const redoEdit =
|
|
311
|
+
export const redo = () => ( { select, dispatch } ) => {
|
|
312
|
+
const redoEdit = select.getRedoEdit();
|
|
329
313
|
if ( ! redoEdit ) {
|
|
330
314
|
return;
|
|
331
315
|
}
|
|
332
|
-
|
|
316
|
+
dispatch( {
|
|
333
317
|
type: 'EDIT_ENTITY_RECORD',
|
|
334
318
|
...redoEdit,
|
|
335
|
-
meta: {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
};
|
|
339
|
-
}
|
|
319
|
+
meta: { isRedo: true },
|
|
320
|
+
} );
|
|
321
|
+
};
|
|
340
322
|
|
|
341
323
|
/**
|
|
342
324
|
* Forces the creation of a new undo level.
|
|
@@ -357,43 +339,37 @@ export function __unstableCreateUndoLevel() {
|
|
|
357
339
|
* @param {boolean} [options.isAutosave=false] Whether this is an autosave.
|
|
358
340
|
* @param {Function} [options.__unstableFetch] Internal use only. Function to
|
|
359
341
|
* call instead of `apiFetch()`.
|
|
360
|
-
* Must return a
|
|
361
|
-
* descriptor.
|
|
342
|
+
* Must return a promise.
|
|
362
343
|
*/
|
|
363
|
-
export
|
|
344
|
+
export const saveEntityRecord = (
|
|
364
345
|
kind,
|
|
365
346
|
name,
|
|
366
347
|
record,
|
|
367
|
-
{ isAutosave = false, __unstableFetch =
|
|
368
|
-
) {
|
|
369
|
-
const entities =
|
|
348
|
+
{ isAutosave = false, __unstableFetch = apiFetch } = {}
|
|
349
|
+
) => async ( { select, resolveSelect, dispatch } ) => {
|
|
350
|
+
const entities = await dispatch( getKindEntities( kind ) );
|
|
370
351
|
const entity = find( entities, { kind, name } );
|
|
371
|
-
if ( ! entity ) {
|
|
352
|
+
if ( ! entity || entity?.__experimentalNoFetch ) {
|
|
372
353
|
return;
|
|
373
354
|
}
|
|
374
355
|
const entityIdKey = entity.key || DEFAULT_ENTITY_KEY;
|
|
375
356
|
const recordId = record[ entityIdKey ];
|
|
376
357
|
|
|
377
|
-
const lock =
|
|
358
|
+
const lock = await dispatch.__unstableAcquireStoreLock(
|
|
378
359
|
STORE_NAME,
|
|
379
360
|
[ 'entities', 'data', kind, name, recordId || uuid() ],
|
|
380
361
|
{ exclusive: true }
|
|
381
362
|
);
|
|
363
|
+
|
|
382
364
|
try {
|
|
383
365
|
// Evaluate optimized edits.
|
|
384
366
|
// (Function edits that should be evaluated on save to avoid expensive computations on every edit.)
|
|
385
367
|
for ( const [ key, value ] of Object.entries( record ) ) {
|
|
386
368
|
if ( typeof value === 'function' ) {
|
|
387
369
|
const evaluatedValue = value(
|
|
388
|
-
|
|
389
|
-
STORE_NAME,
|
|
390
|
-
'getEditedEntityRecord',
|
|
391
|
-
kind,
|
|
392
|
-
name,
|
|
393
|
-
recordId
|
|
394
|
-
)
|
|
370
|
+
select.getEditedEntityRecord( kind, name, recordId )
|
|
395
371
|
);
|
|
396
|
-
|
|
372
|
+
dispatch.editEntityRecord(
|
|
397
373
|
kind,
|
|
398
374
|
name,
|
|
399
375
|
recordId,
|
|
@@ -406,22 +382,20 @@ export function* saveEntityRecord(
|
|
|
406
382
|
}
|
|
407
383
|
}
|
|
408
384
|
|
|
409
|
-
|
|
385
|
+
dispatch( {
|
|
410
386
|
type: 'SAVE_ENTITY_RECORD_START',
|
|
411
387
|
kind,
|
|
412
388
|
name,
|
|
413
389
|
recordId,
|
|
414
390
|
isAutosave,
|
|
415
|
-
};
|
|
391
|
+
} );
|
|
416
392
|
let updatedRecord;
|
|
417
393
|
let error;
|
|
418
394
|
try {
|
|
419
395
|
const path = `${ entity.baseURL }${
|
|
420
396
|
recordId ? '/' + recordId : ''
|
|
421
397
|
}`;
|
|
422
|
-
const persistedRecord =
|
|
423
|
-
STORE_NAME,
|
|
424
|
-
'getRawEntityRecord',
|
|
398
|
+
const persistedRecord = select.getRawEntityRecord(
|
|
425
399
|
kind,
|
|
426
400
|
name,
|
|
427
401
|
recordId
|
|
@@ -432,14 +406,9 @@ export function* saveEntityRecord(
|
|
|
432
406
|
// This is fine for now as it is the only supported autosave,
|
|
433
407
|
// but ideally this should all be handled in the back end,
|
|
434
408
|
// so the client just sends and receives objects.
|
|
435
|
-
const currentUser =
|
|
436
|
-
STORE_NAME,
|
|
437
|
-
'getCurrentUser'
|
|
438
|
-
);
|
|
409
|
+
const currentUser = select.getCurrentUser();
|
|
439
410
|
const currentUserId = currentUser ? currentUser.id : undefined;
|
|
440
|
-
const autosavePost =
|
|
441
|
-
STORE_NAME,
|
|
442
|
-
'getAutosave',
|
|
411
|
+
const autosavePost = resolveSelect.getAutosave(
|
|
443
412
|
persistedRecord.type,
|
|
444
413
|
persistedRecord.id,
|
|
445
414
|
currentUserId
|
|
@@ -454,8 +423,7 @@ export function* saveEntityRecord(
|
|
|
454
423
|
if (
|
|
455
424
|
[ 'title', 'excerpt', 'content' ].includes( key )
|
|
456
425
|
) {
|
|
457
|
-
|
|
458
|
-
acc[ key ] = get( data[ key ], 'raw', data[ key ] );
|
|
426
|
+
acc[ key ] = data[ key ];
|
|
459
427
|
}
|
|
460
428
|
return acc;
|
|
461
429
|
},
|
|
@@ -466,18 +434,12 @@ export function* saveEntityRecord(
|
|
|
466
434
|
: data.status,
|
|
467
435
|
}
|
|
468
436
|
);
|
|
469
|
-
|
|
437
|
+
updatedRecord = await __unstableFetch( {
|
|
470
438
|
path: `${ path }/autosaves`,
|
|
471
439
|
method: 'POST',
|
|
472
440
|
data,
|
|
473
|
-
};
|
|
474
|
-
|
|
475
|
-
updatedRecord = yield __unstableAwaitPromise(
|
|
476
|
-
__unstableFetch( options )
|
|
477
|
-
);
|
|
478
|
-
} else {
|
|
479
|
-
updatedRecord = yield apiFetch( options );
|
|
480
|
-
}
|
|
441
|
+
} );
|
|
442
|
+
|
|
481
443
|
// An autosave may be processed by the server as a regular save
|
|
482
444
|
// when its update is requested by the author and the post had
|
|
483
445
|
// draft or auto-draft status.
|
|
@@ -495,12 +457,7 @@ export function* saveEntityRecord(
|
|
|
495
457
|
key
|
|
496
458
|
)
|
|
497
459
|
) {
|
|
498
|
-
|
|
499
|
-
acc[ key ] = get(
|
|
500
|
-
newRecord[ key ],
|
|
501
|
-
'raw',
|
|
502
|
-
newRecord[ key ]
|
|
503
|
-
);
|
|
460
|
+
acc[ key ] = newRecord[ key ];
|
|
504
461
|
} else if ( key === 'status' ) {
|
|
505
462
|
// Status is only persisted in autosaves when going from
|
|
506
463
|
// "auto-draft" to "draft".
|
|
@@ -511,17 +468,13 @@ export function* saveEntityRecord(
|
|
|
511
468
|
: persistedRecord.status;
|
|
512
469
|
} else {
|
|
513
470
|
// These properties are not persisted in autosaves.
|
|
514
|
-
acc[ key ] =
|
|
515
|
-
persistedRecord[ key ],
|
|
516
|
-
'raw',
|
|
517
|
-
persistedRecord[ key ]
|
|
518
|
-
);
|
|
471
|
+
acc[ key ] = persistedRecord[ key ];
|
|
519
472
|
}
|
|
520
473
|
return acc;
|
|
521
474
|
},
|
|
522
475
|
{}
|
|
523
476
|
);
|
|
524
|
-
|
|
477
|
+
dispatch.receiveEntityRecords(
|
|
525
478
|
kind,
|
|
526
479
|
name,
|
|
527
480
|
newRecord,
|
|
@@ -529,7 +482,10 @@ export function* saveEntityRecord(
|
|
|
529
482
|
true
|
|
530
483
|
);
|
|
531
484
|
} else {
|
|
532
|
-
|
|
485
|
+
dispatch.receiveAutosaves(
|
|
486
|
+
persistedRecord.id,
|
|
487
|
+
updatedRecord
|
|
488
|
+
);
|
|
533
489
|
}
|
|
534
490
|
} else {
|
|
535
491
|
let edits = record;
|
|
@@ -542,19 +498,12 @@ export function* saveEntityRecord(
|
|
|
542
498
|
),
|
|
543
499
|
};
|
|
544
500
|
}
|
|
545
|
-
|
|
501
|
+
updatedRecord = await __unstableFetch( {
|
|
546
502
|
path,
|
|
547
503
|
method: recordId ? 'PUT' : 'POST',
|
|
548
504
|
data: edits,
|
|
549
|
-
};
|
|
550
|
-
|
|
551
|
-
updatedRecord = yield __unstableAwaitPromise(
|
|
552
|
-
__unstableFetch( options )
|
|
553
|
-
);
|
|
554
|
-
} else {
|
|
555
|
-
updatedRecord = yield apiFetch( options );
|
|
556
|
-
}
|
|
557
|
-
yield receiveEntityRecords(
|
|
505
|
+
} );
|
|
506
|
+
dispatch.receiveEntityRecords(
|
|
558
507
|
kind,
|
|
559
508
|
name,
|
|
560
509
|
updatedRecord,
|
|
@@ -566,20 +515,20 @@ export function* saveEntityRecord(
|
|
|
566
515
|
} catch ( _error ) {
|
|
567
516
|
error = _error;
|
|
568
517
|
}
|
|
569
|
-
|
|
518
|
+
dispatch( {
|
|
570
519
|
type: 'SAVE_ENTITY_RECORD_FINISH',
|
|
571
520
|
kind,
|
|
572
521
|
name,
|
|
573
522
|
recordId,
|
|
574
523
|
error,
|
|
575
524
|
isAutosave,
|
|
576
|
-
};
|
|
525
|
+
} );
|
|
577
526
|
|
|
578
527
|
return updatedRecord;
|
|
579
528
|
} finally {
|
|
580
|
-
|
|
529
|
+
dispatch.__unstableReleaseStoreLock( lock );
|
|
581
530
|
}
|
|
582
|
-
}
|
|
531
|
+
};
|
|
583
532
|
|
|
584
533
|
/**
|
|
585
534
|
* Runs multiple core-data actions at the same time using one API request.
|
|
@@ -603,13 +552,12 @@ export function* saveEntityRecord(
|
|
|
603
552
|
* @return {Promise} A promise that resolves to an array containing the return
|
|
604
553
|
* values of each function given in `requests`.
|
|
605
554
|
*/
|
|
606
|
-
export
|
|
555
|
+
export const __experimentalBatch = ( requests ) => async ( { dispatch } ) => {
|
|
607
556
|
const batch = createBatch();
|
|
608
|
-
const dispatch = yield getDispatch();
|
|
609
557
|
const api = {
|
|
610
558
|
saveEntityRecord( kind, name, record, options ) {
|
|
611
559
|
return batch.add( ( add ) =>
|
|
612
|
-
dispatch
|
|
560
|
+
dispatch.saveEntityRecord( kind, name, record, {
|
|
613
561
|
...options,
|
|
614
562
|
__unstableFetch: add,
|
|
615
563
|
} )
|
|
@@ -617,38 +565,28 @@ export function* __experimentalBatch( requests ) {
|
|
|
617
565
|
},
|
|
618
566
|
saveEditedEntityRecord( kind, name, recordId, options ) {
|
|
619
567
|
return batch.add( ( add ) =>
|
|
620
|
-
dispatch(
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
{
|
|
625
|
-
...options,
|
|
626
|
-
__unstableFetch: add,
|
|
627
|
-
}
|
|
628
|
-
)
|
|
568
|
+
dispatch.saveEditedEntityRecord( kind, name, recordId, {
|
|
569
|
+
...options,
|
|
570
|
+
__unstableFetch: add,
|
|
571
|
+
} )
|
|
629
572
|
);
|
|
630
573
|
},
|
|
631
574
|
deleteEntityRecord( kind, name, recordId, query, options ) {
|
|
632
575
|
return batch.add( ( add ) =>
|
|
633
|
-
dispatch(
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
query,
|
|
638
|
-
{
|
|
639
|
-
...options,
|
|
640
|
-
__unstableFetch: add,
|
|
641
|
-
}
|
|
642
|
-
)
|
|
576
|
+
dispatch.deleteEntityRecord( kind, name, recordId, query, {
|
|
577
|
+
...options,
|
|
578
|
+
__unstableFetch: add,
|
|
579
|
+
} )
|
|
643
580
|
);
|
|
644
581
|
},
|
|
645
582
|
};
|
|
646
583
|
const resultPromises = requests.map( ( request ) => request( api ) );
|
|
647
|
-
const [ , ...results ] =
|
|
648
|
-
|
|
649
|
-
|
|
584
|
+
const [ , ...results ] = await Promise.all( [
|
|
585
|
+
batch.run(),
|
|
586
|
+
...resultPromises,
|
|
587
|
+
] );
|
|
650
588
|
return results;
|
|
651
|
-
}
|
|
589
|
+
};
|
|
652
590
|
|
|
653
591
|
/**
|
|
654
592
|
* Action triggered to save an entity record's edits.
|
|
@@ -658,28 +596,23 @@ export function* __experimentalBatch( requests ) {
|
|
|
658
596
|
* @param {Object} recordId ID of the record.
|
|
659
597
|
* @param {Object} options Saving options.
|
|
660
598
|
*/
|
|
661
|
-
export
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
recordId
|
|
669
|
-
) )
|
|
670
|
-
) {
|
|
599
|
+
export const saveEditedEntityRecord = (
|
|
600
|
+
kind,
|
|
601
|
+
name,
|
|
602
|
+
recordId,
|
|
603
|
+
options
|
|
604
|
+
) => async ( { select, dispatch } ) => {
|
|
605
|
+
if ( ! select.hasEditsForEntityRecord( kind, name, recordId ) ) {
|
|
671
606
|
return;
|
|
672
607
|
}
|
|
673
|
-
const edits =
|
|
674
|
-
STORE_NAME,
|
|
675
|
-
'getEntityRecordNonTransientEdits',
|
|
608
|
+
const edits = select.getEntityRecordNonTransientEdits(
|
|
676
609
|
kind,
|
|
677
610
|
name,
|
|
678
611
|
recordId
|
|
679
612
|
);
|
|
680
613
|
const record = { id: recordId, ...edits };
|
|
681
|
-
return
|
|
682
|
-
}
|
|
614
|
+
return await dispatch.saveEntityRecord( kind, name, record, options );
|
|
615
|
+
};
|
|
683
616
|
|
|
684
617
|
/**
|
|
685
618
|
* Action triggered to save only specified properties for the entity.
|
|
@@ -690,27 +623,17 @@ export function* saveEditedEntityRecord( kind, name, recordId, options ) {
|
|
|
690
623
|
* @param {Array} itemsToSave List of entity properties to save.
|
|
691
624
|
* @param {Object} options Saving options.
|
|
692
625
|
*/
|
|
693
|
-
export
|
|
626
|
+
export const __experimentalSaveSpecifiedEntityEdits = (
|
|
694
627
|
kind,
|
|
695
628
|
name,
|
|
696
629
|
recordId,
|
|
697
630
|
itemsToSave,
|
|
698
631
|
options
|
|
699
|
-
) {
|
|
700
|
-
if (
|
|
701
|
-
! ( yield controls.select(
|
|
702
|
-
STORE_NAME,
|
|
703
|
-
'hasEditsForEntityRecord',
|
|
704
|
-
kind,
|
|
705
|
-
name,
|
|
706
|
-
recordId
|
|
707
|
-
) )
|
|
708
|
-
) {
|
|
632
|
+
) => async ( { select, dispatch } ) => {
|
|
633
|
+
if ( ! select.hasEditsForEntityRecord( kind, name, recordId ) ) {
|
|
709
634
|
return;
|
|
710
635
|
}
|
|
711
|
-
const edits =
|
|
712
|
-
STORE_NAME,
|
|
713
|
-
'getEntityRecordNonTransientEdits',
|
|
636
|
+
const edits = select.getEntityRecordNonTransientEdits(
|
|
714
637
|
kind,
|
|
715
638
|
name,
|
|
716
639
|
recordId
|
|
@@ -721,8 +644,8 @@ export function* __experimentalSaveSpecifiedEntityEdits(
|
|
|
721
644
|
editsToSave[ edit ] = edits[ edit ];
|
|
722
645
|
}
|
|
723
646
|
}
|
|
724
|
-
return
|
|
725
|
-
}
|
|
647
|
+
return await dispatch.saveEntityRecord( kind, name, editsToSave, options );
|
|
648
|
+
};
|
|
726
649
|
|
|
727
650
|
/**
|
|
728
651
|
* Returns an action object used in signalling that Upload permissions have been received.
|
|
@@ -1,10 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { chunk } from 'lodash';
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* WordPress dependencies
|
|
3
8
|
*/
|
|
4
9
|
import apiFetch from '@wordpress/api-fetch';
|
|
5
10
|
|
|
6
11
|
/**
|
|
7
|
-
*
|
|
12
|
+
* Maximum number of requests to place in a single batch request. Obtained by
|
|
13
|
+
* sending a preflight OPTIONS request to /batch/v1/.
|
|
14
|
+
*
|
|
15
|
+
* @type {number?}
|
|
16
|
+
*/
|
|
17
|
+
let maxItems = null;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Default batch processor. Sends its input requests to /batch/v1.
|
|
8
21
|
*
|
|
9
22
|
* @param {Array} requests List of API requests to perform at once.
|
|
10
23
|
*
|
|
@@ -13,33 +26,51 @@ import apiFetch from '@wordpress/api-fetch';
|
|
|
13
26
|
* (if not ).
|
|
14
27
|
*/
|
|
15
28
|
export default async function defaultProcessor( requests ) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
path: request.path,
|
|
23
|
-
body: request.data, // Rename 'data' to 'body'.
|
|
24
|
-
method: request.method,
|
|
25
|
-
headers: request.headers,
|
|
26
|
-
} ) ),
|
|
27
|
-
},
|
|
28
|
-
} );
|
|
29
|
-
|
|
30
|
-
if ( batchResponse.failed ) {
|
|
31
|
-
return batchResponse.responses.map( ( response ) => ( {
|
|
32
|
-
error: response?.body,
|
|
33
|
-
} ) );
|
|
29
|
+
if ( maxItems === null ) {
|
|
30
|
+
const preflightResponse = await apiFetch( {
|
|
31
|
+
path: '/batch/v1',
|
|
32
|
+
method: 'OPTIONS',
|
|
33
|
+
} );
|
|
34
|
+
maxItems = preflightResponse.endpoints[ 0 ].args.requests.maxItems;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
const results = [];
|
|
38
|
+
|
|
39
|
+
for ( const batchRequests of chunk( requests, maxItems ) ) {
|
|
40
|
+
const batchResponse = await apiFetch( {
|
|
41
|
+
path: '/batch/v1',
|
|
42
|
+
method: 'POST',
|
|
43
|
+
data: {
|
|
44
|
+
validation: 'require-all-validate',
|
|
45
|
+
requests: batchRequests.map( ( request ) => ( {
|
|
46
|
+
path: request.path,
|
|
47
|
+
body: request.data, // Rename 'data' to 'body'.
|
|
48
|
+
method: request.method,
|
|
49
|
+
headers: request.headers,
|
|
50
|
+
} ) ),
|
|
51
|
+
},
|
|
52
|
+
} );
|
|
53
|
+
|
|
54
|
+
let batchResults;
|
|
55
|
+
|
|
56
|
+
if ( batchResponse.failed ) {
|
|
57
|
+
batchResults = batchResponse.responses.map( ( response ) => ( {
|
|
58
|
+
error: response?.body,
|
|
59
|
+
} ) );
|
|
40
60
|
} else {
|
|
41
|
-
|
|
61
|
+
batchResults = batchResponse.responses.map( ( response ) => {
|
|
62
|
+
const result = {};
|
|
63
|
+
if ( response.status >= 200 && response.status < 300 ) {
|
|
64
|
+
result.output = response.body;
|
|
65
|
+
} else {
|
|
66
|
+
result.error = response.body;
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
} );
|
|
42
70
|
}
|
|
43
|
-
|
|
44
|
-
|
|
71
|
+
|
|
72
|
+
results.push( ...batchResults );
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return results;
|
|
45
76
|
}
|