@wordpress/core-data 6.10.0 → 6.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +4 -0
  3. package/build/actions.js +252 -276
  4. package/build/actions.js.map +1 -1
  5. package/build/batch/create-batch.js +8 -16
  6. package/build/batch/create-batch.js.map +1 -1
  7. package/build/batch/default-processor.js +1 -1
  8. package/build/batch/default-processor.js.map +1 -1
  9. package/build/entities.js +16 -25
  10. package/build/entities.js.map +1 -1
  11. package/build/entity-provider.js +12 -17
  12. package/build/entity-provider.js.map +1 -1
  13. package/build/fetch/__experimental-fetch-link-suggestions.js +2 -6
  14. package/build/fetch/__experimental-fetch-link-suggestions.js.map +1 -1
  15. package/build/fetch/__experimental-fetch-url-data.js +1 -2
  16. package/build/fetch/__experimental-fetch-url-data.js.map +1 -1
  17. package/build/hooks/use-entity-record.js +7 -11
  18. package/build/hooks/use-entity-record.js.map +1 -1
  19. package/build/hooks/use-entity-records.js +3 -5
  20. package/build/hooks/use-entity-records.js.map +1 -1
  21. package/build/hooks/use-query-select.js +1 -6
  22. package/build/hooks/use-query-select.js.map +1 -1
  23. package/build/index.js +1 -7
  24. package/build/index.js.map +1 -1
  25. package/build/locks/actions.js +3 -4
  26. package/build/locks/actions.js.map +1 -1
  27. package/build/locks/reducer.js +1 -4
  28. package/build/locks/reducer.js.map +1 -1
  29. package/build/locks/selectors.js +3 -4
  30. package/build/locks/selectors.js.map +1 -1
  31. package/build/locks/utils.js +3 -5
  32. package/build/locks/utils.js.map +1 -1
  33. package/build/private-selectors.js +37 -0
  34. package/build/private-selectors.js.map +1 -0
  35. package/build/queried-data/actions.js +2 -5
  36. package/build/queried-data/actions.js.map +1 -1
  37. package/build/queried-data/reducer.js +17 -47
  38. package/build/queried-data/reducer.js.map +1 -1
  39. package/build/queried-data/selectors.js +4 -11
  40. package/build/queried-data/selectors.js.map +1 -1
  41. package/build/reducer.js +167 -194
  42. package/build/reducer.js.map +1 -1
  43. package/build/resolvers.js +175 -220
  44. package/build/resolvers.js.map +1 -1
  45. package/build/selectors.js +53 -61
  46. package/build/selectors.js.map +1 -1
  47. package/build/utils/forward-resolver.js +4 -11
  48. package/build/utils/forward-resolver.js.map +1 -1
  49. package/build/utils/on-sub-key.js +1 -3
  50. package/build/utils/on-sub-key.js.map +1 -1
  51. package/build-module/actions.js +251 -276
  52. package/build-module/actions.js.map +1 -1
  53. package/build-module/batch/create-batch.js +8 -16
  54. package/build-module/batch/create-batch.js.map +1 -1
  55. package/build-module/batch/default-processor.js +1 -1
  56. package/build-module/batch/default-processor.js.map +1 -1
  57. package/build-module/entities.js +16 -25
  58. package/build-module/entities.js.map +1 -1
  59. package/build-module/entity-provider.js +12 -17
  60. package/build-module/entity-provider.js.map +1 -1
  61. package/build-module/fetch/__experimental-fetch-link-suggestions.js +2 -6
  62. package/build-module/fetch/__experimental-fetch-link-suggestions.js.map +1 -1
  63. package/build-module/fetch/__experimental-fetch-url-data.js +1 -2
  64. package/build-module/fetch/__experimental-fetch-url-data.js.map +1 -1
  65. package/build-module/hooks/use-entity-record.js +7 -11
  66. package/build-module/hooks/use-entity-record.js.map +1 -1
  67. package/build-module/hooks/use-entity-records.js +3 -5
  68. package/build-module/hooks/use-entity-records.js.map +1 -1
  69. package/build-module/hooks/use-query-select.js +1 -6
  70. package/build-module/hooks/use-query-select.js.map +1 -1
  71. package/build-module/index.js +1 -7
  72. package/build-module/index.js.map +1 -1
  73. package/build-module/locks/actions.js +3 -4
  74. package/build-module/locks/actions.js.map +1 -1
  75. package/build-module/locks/reducer.js +1 -4
  76. package/build-module/locks/reducer.js.map +1 -1
  77. package/build-module/locks/selectors.js +3 -4
  78. package/build-module/locks/selectors.js.map +1 -1
  79. package/build-module/locks/utils.js +3 -5
  80. package/build-module/locks/utils.js.map +1 -1
  81. package/build-module/private-selectors.js +28 -0
  82. package/build-module/private-selectors.js.map +1 -0
  83. package/build-module/queried-data/actions.js +2 -5
  84. package/build-module/queried-data/actions.js.map +1 -1
  85. package/build-module/queried-data/reducer.js +17 -47
  86. package/build-module/queried-data/reducer.js.map +1 -1
  87. package/build-module/queried-data/selectors.js +4 -11
  88. package/build-module/queried-data/selectors.js.map +1 -1
  89. package/build-module/reducer.js +168 -194
  90. package/build-module/reducer.js.map +1 -1
  91. package/build-module/resolvers.js +175 -220
  92. package/build-module/resolvers.js.map +1 -1
  93. package/build-module/selectors.js +55 -61
  94. package/build-module/selectors.js.map +1 -1
  95. package/build-module/utils/forward-resolver.js +4 -11
  96. package/build-module/utils/forward-resolver.js.map +1 -1
  97. package/build-module/utils/on-sub-key.js +1 -3
  98. package/build-module/utils/on-sub-key.js.map +1 -1
  99. package/build-types/actions.d.ts.map +1 -1
  100. package/build-types/private-selectors.d.ts +25 -0
  101. package/build-types/private-selectors.d.ts.map +1 -0
  102. package/build-types/reducer.d.ts +6 -2
  103. package/build-types/reducer.d.ts.map +1 -1
  104. package/build-types/selectors.d.ts +16 -4
  105. package/build-types/selectors.d.ts.map +1 -1
  106. package/package.json +13 -13
  107. package/src/actions.js +9 -8
  108. package/src/index.js +0 -1
  109. package/src/private-selectors.ts +30 -0
  110. package/src/reducer.js +130 -104
  111. package/src/selectors.ts +33 -13
  112. package/src/test/reducer.js +89 -54
  113. package/src/test/selectors.js +8 -8
  114. package/tsconfig.tsbuildinfo +1 -1
@@ -30,10 +30,7 @@ import { rootEntitiesConfig, DEFAULT_ENTITY_KEY } from './entities';
30
30
  * @return {Object} Updated state.
31
31
  */
32
32
 
33
- export function terms() {
34
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
35
- let action = arguments.length > 1 ? arguments[1] : undefined;
36
-
33
+ export function terms(state = {}, action) {
37
34
  switch (action.type) {
38
35
  case 'RECEIVE_TERMS':
39
36
  return { ...state,
@@ -52,13 +49,10 @@ export function terms() {
52
49
  * @return {Object} Updated state.
53
50
  */
54
51
 
55
- export function users() {
56
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
57
- byId: {},
58
- queries: {}
59
- };
60
- let action = arguments.length > 1 ? arguments[1] : undefined;
61
-
52
+ export function users(state = {
53
+ byId: {},
54
+ queries: {}
55
+ }, action) {
62
56
  switch (action.type) {
63
57
  case 'RECEIVE_USER_QUERY':
64
58
  return {
@@ -85,10 +79,7 @@ export function users() {
85
79
  * @return {Object} Updated state.
86
80
  */
87
81
 
88
- export function currentUser() {
89
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
90
- let action = arguments.length > 1 ? arguments[1] : undefined;
91
-
82
+ export function currentUser(state = {}, action) {
92
83
  switch (action.type) {
93
84
  case 'RECEIVE_CURRENT_USER':
94
85
  return action.currentUser;
@@ -105,10 +96,7 @@ export function currentUser() {
105
96
  * @return {Object} Updated state.
106
97
  */
107
98
 
108
- export function taxonomies() {
109
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
110
- let action = arguments.length > 1 ? arguments[1] : undefined;
111
-
99
+ export function taxonomies(state = [], action) {
112
100
  switch (action.type) {
113
101
  case 'RECEIVE_TAXONOMIES':
114
102
  return action.taxonomies;
@@ -125,10 +113,7 @@ export function taxonomies() {
125
113
  * @return {string|undefined} Updated state.
126
114
  */
127
115
 
128
- export function currentTheme() {
129
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
130
- let action = arguments.length > 1 ? arguments[1] : undefined;
131
-
116
+ export function currentTheme(state = undefined, action) {
132
117
  switch (action.type) {
133
118
  case 'RECEIVE_CURRENT_THEME':
134
119
  return action.currentTheme.stylesheet;
@@ -145,10 +130,7 @@ export function currentTheme() {
145
130
  * @return {string|undefined} Updated state.
146
131
  */
147
132
 
148
- export function currentGlobalStylesId() {
149
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
150
- let action = arguments.length > 1 ? arguments[1] : undefined;
151
-
133
+ export function currentGlobalStylesId(state = undefined, action) {
152
134
  switch (action.type) {
153
135
  case 'RECEIVE_CURRENT_GLOBAL_STYLES_ID':
154
136
  return action.id;
@@ -165,10 +147,7 @@ export function currentGlobalStylesId() {
165
147
  * @return {Record<string, object>} Updated state.
166
148
  */
167
149
 
168
- export function themeBaseGlobalStyles() {
169
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
170
- let action = arguments.length > 1 ? arguments[1] : undefined;
171
-
150
+ export function themeBaseGlobalStyles(state = {}, action) {
172
151
  switch (action.type) {
173
152
  case 'RECEIVE_THEME_GLOBAL_STYLES':
174
153
  return { ...state,
@@ -187,10 +166,7 @@ export function themeBaseGlobalStyles() {
187
166
  * @return {Record<string, object>} Updated state.
188
167
  */
189
168
 
190
- export function themeGlobalStyleVariations() {
191
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
192
- let action = arguments.length > 1 ? arguments[1] : undefined;
193
-
169
+ export function themeGlobalStyleVariations(state = {}, action) {
194
170
  switch (action.type) {
195
171
  case 'RECEIVE_THEME_GLOBAL_STYLE_VARIATIONS':
196
172
  return { ...state,
@@ -200,6 +176,36 @@ export function themeGlobalStyleVariations() {
200
176
 
201
177
  return state;
202
178
  }
179
+
180
+ const withMultiEntityRecordEdits = reducer => (state, action) => {
181
+ if (action.type === 'UNDO' || action.type === 'REDO') {
182
+ const {
183
+ stackedEdits
184
+ } = action;
185
+ let newState = state;
186
+ stackedEdits.forEach(({
187
+ kind,
188
+ name,
189
+ recordId,
190
+ property,
191
+ from,
192
+ to
193
+ }) => {
194
+ newState = reducer(newState, {
195
+ type: 'EDIT_ENTITY_RECORD',
196
+ kind,
197
+ name,
198
+ recordId,
199
+ edits: {
200
+ [property]: action.type === 'UNDO' ? from : to
201
+ }
202
+ });
203
+ });
204
+ return newState;
205
+ }
206
+
207
+ return reducer(state, action);
208
+ };
203
209
  /**
204
210
  * Higher Order Reducer for a given entity config. It supports:
205
211
  *
@@ -212,8 +218,9 @@ export function themeGlobalStyleVariations() {
212
218
  * @return {AnyFunction} Reducer.
213
219
  */
214
220
 
221
+
215
222
  function entity(entityConfig) {
216
- return compose([// Limit to matching action type so we don't attempt to replace action on
223
+ return compose([withMultiEntityRecordEdits, // Limit to matching action type so we don't attempt to replace action on
217
224
  // an unhandled action.
218
225
  ifMatchingAction(action => action.name && action.kind && action.name === entityConfig.name && action.kind === entityConfig.kind), // Inject the entity config into the action.
219
226
  replaceAction(action => {
@@ -222,15 +229,12 @@ function entity(entityConfig) {
222
229
  };
223
230
  })])(combineReducers({
224
231
  queriedData: queriedDataReducer,
225
- edits: function () {
226
- var _action$query$context, _action$query;
227
-
228
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
229
- let action = arguments.length > 1 ? arguments[1] : undefined;
232
+ edits: (state = {}, action) => {
233
+ var _action$query$context;
230
234
 
231
235
  switch (action.type) {
232
236
  case 'RECEIVE_ITEMS':
233
- const context = (_action$query$context = action === null || action === void 0 ? void 0 : (_action$query = action.query) === null || _action$query === void 0 ? void 0 : _action$query.context) !== null && _action$query$context !== void 0 ? _action$query$context : 'default';
237
+ const context = (_action$query$context = action?.query?.context) !== null && _action$query$context !== void 0 ? _action$query$context : 'default';
234
238
 
235
239
  if (context !== 'default') {
236
240
  return state;
@@ -248,14 +252,14 @@ function entity(entityConfig) {
248
252
  }
249
253
 
250
254
  const nextEdits = Object.keys(edits).reduce((acc, key) => {
251
- var _record$key$raw, _record$key;
255
+ var _record$key$raw;
252
256
 
253
257
  // If the edited value is still different to the persisted value,
254
258
  // keep the edited value in edits.
255
259
  if ( // Edits are the "raw" attribute values, but records may have
256
260
  // objects with more properties, so we use `get` here for the
257
261
  // comparison.
258
- !fastDeepEqual(edits[key], (_record$key$raw = (_record$key = record[key]) === null || _record$key === void 0 ? void 0 : _record$key.raw) !== null && _record$key$raw !== void 0 ? _record$key$raw : record[key]) && ( // Sometimes the server alters the sent value which means
262
+ !fastDeepEqual(edits[key], (_record$key$raw = record[key]?.raw) !== null && _record$key$raw !== void 0 ? _record$key$raw : record[key]) && ( // Sometimes the server alters the sent value which means
259
263
  // we need to also remove the edits before the api request.
260
264
  !action.persistedEdits || !fastDeepEqual(edits[key], action.persistedEdits[key]))) {
261
265
  acc[key] = edits[key];
@@ -291,10 +295,7 @@ function entity(entityConfig) {
291
295
 
292
296
  return state;
293
297
  },
294
- saving: function () {
295
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
296
- let action = arguments.length > 1 ? arguments[1] : undefined;
297
-
298
+ saving: (state = {}, action) => {
298
299
  switch (action.type) {
299
300
  case 'SAVE_ENTITY_RECORD_START':
300
301
  case 'SAVE_ENTITY_RECORD_FINISH':
@@ -309,10 +310,7 @@ function entity(entityConfig) {
309
310
 
310
311
  return state;
311
312
  },
312
- deleting: function () {
313
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
314
- let action = arguments.length > 1 ? arguments[1] : undefined;
315
-
313
+ deleting: (state = {}, action) => {
316
314
  switch (action.type) {
317
315
  case 'DELETE_ENTITY_RECORD_START':
318
316
  case 'DELETE_ENTITY_RECORD_FINISH':
@@ -338,10 +336,7 @@ function entity(entityConfig) {
338
336
  */
339
337
 
340
338
 
341
- export function entitiesConfig() {
342
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : rootEntitiesConfig;
343
- let action = arguments.length > 1 ? arguments[1] : undefined;
344
-
339
+ export function entitiesConfig(state = rootEntitiesConfig, action) {
345
340
  switch (action.type) {
346
341
  case 'ADD_ENTITIES':
347
342
  return [...state, ...action.entities];
@@ -358,9 +353,7 @@ export function entitiesConfig() {
358
353
  * @return {Object} Updated state.
359
354
  */
360
355
 
361
- export const entities = function () {
362
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
363
- let action = arguments.length > 1 ? arguments[1] : undefined;
356
+ export const entities = (state = {}, action) => {
364
357
  const newConfig = entitiesConfig(state.config, action); // Generates a dynamic reducer for the entities.
365
358
 
366
359
  let entitiesDataReducer = state.reducer;
@@ -378,8 +371,7 @@ export const entities = function () {
378
371
  acc[kind].push(record);
379
372
  return acc;
380
373
  }, {});
381
- entitiesDataReducer = combineReducers(Object.entries(entitiesByKind).reduce((memo, _ref) => {
382
- let [kind, subEntities] = _ref;
374
+ entitiesDataReducer = combineReducers(Object.entries(entitiesByKind).reduce((memo, [kind, subEntities]) => {
383
375
  const kindReducer = combineReducers(subEntities.reduce((kindMemo, entityConfig) => ({ ...kindMemo,
384
376
  [entityConfig.name]: entity(entityConfig)
385
377
  }), {}));
@@ -403,8 +395,9 @@ export const entities = function () {
403
395
  /**
404
396
  * @typedef {Object} UndoStateMeta
405
397
  *
406
- * @property {number} offset Where in the undo stack we are.
407
- * @property {Object} [flattenedUndo] Flattened form of undo stack.
398
+ * @property {number} list The undo stack.
399
+ * @property {number} offset Where in the undo stack we are.
400
+ * @property {Object} cache Cache of unpersisted transient edits.
408
401
  */
409
402
 
410
403
  /** @typedef {Array<Object> & UndoStateMeta} UndoState */
@@ -415,12 +408,10 @@ export const entities = function () {
415
408
  * @todo Given how we use this we might want to make a custom class for it.
416
409
  */
417
410
 
418
- const UNDO_INITIAL_STATE = Object.assign([], {
411
+ const UNDO_INITIAL_STATE = {
412
+ list: [],
419
413
  offset: 0
420
- });
421
- /** @type {Object} */
422
-
423
- let lastEditAction;
414
+ };
424
415
  /**
425
416
  * Reducer keeping track of entity edit undo history.
426
417
  *
@@ -430,117 +421,121 @@ let lastEditAction;
430
421
  * @return {UndoState} Updated state.
431
422
  */
432
423
 
433
- export function undo() {
434
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : UNDO_INITIAL_STATE;
435
- let action = arguments.length > 1 ? arguments[1] : undefined;
424
+ export function undo(state = UNDO_INITIAL_STATE, action) {
425
+ const omitPendingRedos = currentState => {
426
+ return { ...currentState,
427
+ list: currentState.list.slice(0, currentState.offset || undefined),
428
+ offset: 0
429
+ };
430
+ };
436
431
 
437
- switch (action.type) {
438
- case 'EDIT_ENTITY_RECORD':
439
- case 'CREATE_UNDO_LEVEL':
440
- let isCreateUndoLevel = action.type === 'CREATE_UNDO_LEVEL';
441
- const isUndoOrRedo = !isCreateUndoLevel && (action.meta.isUndo || action.meta.isRedo);
442
-
443
- if (isCreateUndoLevel) {
444
- action = lastEditAction;
445
- } else if (!isUndoOrRedo) {
446
- // Don't lose the last edit cache if the new one only has transient edits.
447
- // Transient edits don't create new levels so updating the cache would make
448
- // us skip an edit later when creating levels explicitly.
449
- if (Object.keys(action.edits).some(key => !action.transientEdits[key])) {
450
- lastEditAction = action;
451
- } else {
452
- lastEditAction = { ...action,
453
- edits: { ...(lastEditAction && lastEditAction.edits),
454
- ...action.edits
455
- }
456
- };
457
- }
458
- }
459
- /** @type {UndoState} */
460
-
461
-
462
- let nextState;
463
-
464
- if (isUndoOrRedo) {
465
- // @ts-ignore we might consider using Object.assign({}, state)
466
- nextState = [...state];
467
- nextState.offset = state.offset + (action.meta.isUndo ? -1 : 1);
468
-
469
- if (state.flattenedUndo) {
470
- // The first undo in a sequence of undos might happen while we have
471
- // flattened undos in state. If this is the case, we want execution
472
- // to continue as if we were creating an explicit undo level. This
473
- // will result in an extra undo level being appended with the flattened
474
- // undo values.
475
- // We also have to take into account if the `lastEditAction` had opted out
476
- // of being tracked in undo history, like the action that persists the latest
477
- // content right before saving. In that case we have to update the `lastEditAction`
478
- // to avoid returning early before applying the existing flattened undos.
479
- isCreateUndoLevel = true;
480
-
481
- if (!lastEditAction.meta.undo) {
482
- lastEditAction.meta.undo = {
483
- edits: {}
484
- };
485
- }
432
+ const appendCachedEditsToLastUndo = currentState => {
433
+ if (!currentState.cache) {
434
+ return currentState;
435
+ }
486
436
 
487
- action = lastEditAction;
488
- } else {
489
- return nextState;
490
- }
491
- }
437
+ let nextState = { ...currentState,
438
+ list: [...currentState.list]
439
+ };
440
+ nextState = omitPendingRedos(nextState);
441
+ const previousUndoState = nextState.list.pop();
442
+ const updatedUndoState = currentState.cache.reduce(appendEditToStack, previousUndoState);
443
+ nextState.list.push(updatedUndoState);
444
+ return { ...nextState,
445
+ cache: undefined
446
+ };
447
+ };
492
448
 
493
- if (!action.meta.undo) {
494
- return state;
495
- } // Transient edits don't create an undo level, but are
496
- // reachable in the next meaningful edit to which they
497
- // are merged. They are defined in the entity's config.
449
+ const appendEditToStack = (stack = [], {
450
+ kind,
451
+ name,
452
+ recordId,
453
+ property,
454
+ from,
455
+ to
456
+ }) => {
457
+ const existingEditIndex = stack?.findIndex(({
458
+ kind: k,
459
+ name: n,
460
+ recordId: r,
461
+ property: p
462
+ }) => {
463
+ return k === kind && n === name && r === recordId && p === property;
464
+ });
465
+ const nextStack = [...stack];
466
+
467
+ if (existingEditIndex !== -1) {
468
+ // If the edit is already in the stack leave the initial "from" value.
469
+ nextStack[existingEditIndex] = { ...nextStack[existingEditIndex],
470
+ to
471
+ };
472
+ } else {
473
+ nextStack.push({
474
+ kind,
475
+ name,
476
+ recordId,
477
+ property,
478
+ from,
479
+ to
480
+ });
481
+ }
498
482
 
483
+ return nextStack;
484
+ };
499
485
 
500
- if (!isCreateUndoLevel && !Object.keys(action.edits).some(key => !action.transientEdits[key])) {
501
- // @ts-ignore we might consider using Object.assign({}, state)
502
- nextState = [...state];
503
- nextState.flattenedUndo = { ...state.flattenedUndo,
504
- ...action.edits
486
+ switch (action.type) {
487
+ case 'CREATE_UNDO_LEVEL':
488
+ return appendCachedEditsToLastUndo(state);
489
+
490
+ case 'UNDO':
491
+ case 'REDO':
492
+ {
493
+ const nextState = appendCachedEditsToLastUndo(state);
494
+ return { ...nextState,
495
+ offset: state.offset + (action.type === 'UNDO' ? -1 : 1)
505
496
  };
506
- nextState.offset = state.offset;
507
- return nextState;
508
- } // Clear potential redos, because this only supports linear history.
509
-
497
+ }
510
498
 
511
- nextState = // @ts-ignore this needs additional cleanup, probably involving code-level changes
512
- nextState || state.slice(0, state.offset || undefined);
513
- nextState.offset = nextState.offset || 0;
514
- nextState.pop();
499
+ case 'EDIT_ENTITY_RECORD':
500
+ {
501
+ if (!action.meta.undo) {
502
+ return state;
503
+ }
515
504
 
516
- if (!isCreateUndoLevel) {
517
- nextState.push({
518
- kind: action.meta.undo.kind,
519
- name: action.meta.undo.name,
520
- recordId: action.meta.undo.recordId,
521
- edits: { ...state.flattenedUndo,
522
- ...action.meta.undo.edits
523
- }
505
+ const isCachedChange = Object.keys(action.edits).every(key => action.transientEdits[key]);
506
+ const edits = Object.keys(action.edits).map(key => {
507
+ return {
508
+ kind: action.kind,
509
+ name: action.name,
510
+ recordId: action.recordId,
511
+ property: key,
512
+ from: action.meta.undo.edits[key],
513
+ to: action.edits[key]
514
+ };
524
515
  });
525
- } // When an edit is a function it's an optimization to avoid running some expensive operation.
526
- // We can't rely on the function references being the same so we opt out of comparing them here.
527
516
 
517
+ if (isCachedChange) {
518
+ return { ...state,
519
+ cache: edits.reduce(appendEditToStack, state.cache)
520
+ };
521
+ }
528
522
 
529
- const comparisonUndoEdits = Object.values(action.meta.undo.edits).filter(edit => typeof edit !== 'function');
530
- const comparisonEdits = Object.values(action.edits).filter(edit => typeof edit !== 'function');
523
+ let nextState = omitPendingRedos(state);
524
+ nextState = appendCachedEditsToLastUndo(nextState);
525
+ nextState = { ...nextState,
526
+ list: [...nextState.list]
527
+ }; // When an edit is a function it's an optimization to avoid running some expensive operation.
528
+ // We can't rely on the function references being the same so we opt out of comparing them here.
531
529
 
532
- if (!isShallowEqual(comparisonUndoEdits, comparisonEdits)) {
533
- nextState.push({
534
- kind: action.kind,
535
- name: action.name,
536
- recordId: action.recordId,
537
- edits: isCreateUndoLevel ? { ...state.flattenedUndo,
538
- ...action.edits
539
- } : action.edits
540
- });
541
- }
530
+ const comparisonUndoEdits = Object.values(action.meta.undo.edits).filter(edit => typeof edit !== 'function');
531
+ const comparisonEdits = Object.values(action.edits).filter(edit => typeof edit !== 'function');
532
+
533
+ if (!isShallowEqual(comparisonUndoEdits, comparisonEdits)) {
534
+ nextState.list.push(edits);
535
+ }
542
536
 
543
- return nextState;
537
+ return nextState;
538
+ }
544
539
  }
545
540
 
546
541
  return state;
@@ -554,10 +549,7 @@ export function undo() {
554
549
  * @return {Object} Updated state.
555
550
  */
556
551
 
557
- export function embedPreviews() {
558
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
559
- let action = arguments.length > 1 ? arguments[1] : undefined;
560
-
552
+ export function embedPreviews(state = {}, action) {
561
553
  switch (action.type) {
562
554
  case 'RECEIVE_EMBED_PREVIEW':
563
555
  const {
@@ -581,10 +573,7 @@ export function embedPreviews() {
581
573
  * @return {Object} Updated state.
582
574
  */
583
575
 
584
- export function userPermissions() {
585
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
586
- let action = arguments.length > 1 ? arguments[1] : undefined;
587
-
576
+ export function userPermissions(state = {}, action) {
588
577
  switch (action.type) {
589
578
  case 'RECEIVE_USER_PERMISSION':
590
579
  return { ...state,
@@ -603,10 +592,7 @@ export function userPermissions() {
603
592
  * @return {Object} Updated state.
604
593
  */
605
594
 
606
- export function autosaves() {
607
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
608
- let action = arguments.length > 1 ? arguments[1] : undefined;
609
-
595
+ export function autosaves(state = {}, action) {
610
596
  switch (action.type) {
611
597
  case 'RECEIVE_AUTOSAVES':
612
598
  const {
@@ -620,10 +606,7 @@ export function autosaves() {
620
606
 
621
607
  return state;
622
608
  }
623
- export function blockPatterns() {
624
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
625
- let action = arguments.length > 1 ? arguments[1] : undefined;
626
-
609
+ export function blockPatterns(state = [], action) {
627
610
  switch (action.type) {
628
611
  case 'RECEIVE_BLOCK_PATTERNS':
629
612
  return action.patterns;
@@ -631,10 +614,7 @@ export function blockPatterns() {
631
614
 
632
615
  return state;
633
616
  }
634
- export function blockPatternCategories() {
635
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
636
- let action = arguments.length > 1 ? arguments[1] : undefined;
637
-
617
+ export function blockPatternCategories(state = [], action) {
638
618
  switch (action.type) {
639
619
  case 'RECEIVE_BLOCK_PATTERN_CATEGORIES':
640
620
  return action.categories;
@@ -642,10 +622,7 @@ export function blockPatternCategories() {
642
622
 
643
623
  return state;
644
624
  }
645
- export function navigationFallbackId() {
646
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
647
- let action = arguments.length > 1 ? arguments[1] : undefined;
648
-
625
+ export function navigationFallbackId(state = null, action) {
649
626
  switch (action.type) {
650
627
  case 'RECEIVE_NAVIGATION_FALLBACK_ID':
651
628
  return action.fallbackId;
@@ -662,10 +639,7 @@ export function navigationFallbackId() {
662
639
  * @return {Record<string, object>} Updated state.
663
640
  */
664
641
 
665
- export function themeGlobalStyleRevisions() {
666
- let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
667
- let action = arguments.length > 1 ? arguments[1] : undefined;
668
-
642
+ export function themeGlobalStyleRevisions(state = {}, action) {
669
643
  switch (action.type) {
670
644
  case 'RECEIVE_THEME_GLOBAL_STYLE_REVISIONS':
671
645
  return { ...state,