@wordpress/core-data 7.48.1 → 7.48.2-next.v.202606191442.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.
- package/build/actions.cjs +1 -7
- package/build/actions.cjs.map +3 -3
- package/build/entities.cjs +2 -1
- package/build/entities.cjs.map +2 -2
- package/build/entity-types/helpers.cjs.map +1 -1
- package/build/hooks/use-entity-record.cjs +21 -19
- package/build/hooks/use-entity-record.cjs.map +3 -3
- package/build/hooks/use-entity-records.cjs +22 -20
- package/build/hooks/use-entity-records.cjs.map +3 -3
- package/build/hooks/use-post-editor-awareness-state.cjs.map +1 -1
- package/build/hooks/use-query-select.cjs +2 -20
- package/build/hooks/use-query-select.cjs.map +2 -2
- package/build/hooks/utils.cjs +53 -0
- package/build/hooks/utils.cjs.map +7 -0
- package/build/reducer.cjs +10 -7
- package/build/reducer.cjs.map +2 -2
- package/build/types.cjs.map +1 -1
- package/build/utils/clear-unchanged-edits.cjs +51 -0
- package/build/utils/clear-unchanged-edits.cjs.map +7 -0
- package/build/utils/crdt-blocks.cjs.map +1 -1
- package/build/utils/crdt-user-selections.cjs.map +1 -1
- package/build/utils/crdt-utils.cjs.map +1 -1
- package/build/utils/crdt.cjs.map +1 -1
- package/build/utils/index.cjs +3 -0
- package/build/utils/index.cjs.map +2 -2
- package/build/utils/set-nested-value.cjs.map +1 -1
- package/build-module/actions.mjs +2 -8
- package/build-module/actions.mjs.map +2 -2
- package/build-module/entities.mjs +2 -1
- package/build-module/entities.mjs.map +2 -2
- package/build-module/hooks/use-entity-record.mjs +21 -19
- package/build-module/hooks/use-entity-record.mjs.map +2 -2
- package/build-module/hooks/use-entity-records.mjs +20 -18
- package/build-module/hooks/use-entity-records.mjs.map +2 -2
- package/build-module/hooks/use-post-editor-awareness-state.mjs.map +1 -1
- package/build-module/hooks/use-query-select.mjs +2 -20
- package/build-module/hooks/use-query-select.mjs.map +2 -2
- package/build-module/hooks/utils.mjs +28 -0
- package/build-module/hooks/utils.mjs.map +7 -0
- package/build-module/reducer.mjs +11 -8
- package/build-module/reducer.mjs.map +2 -2
- package/build-module/utils/clear-unchanged-edits.mjs +20 -0
- package/build-module/utils/clear-unchanged-edits.mjs.map +7 -0
- package/build-module/utils/crdt-blocks.mjs.map +1 -1
- package/build-module/utils/crdt-user-selections.mjs.map +1 -1
- package/build-module/utils/crdt-utils.mjs.map +1 -1
- package/build-module/utils/crdt.mjs.map +1 -1
- package/build-module/utils/index.mjs +22 -20
- package/build-module/utils/index.mjs.map +2 -2
- package/build-module/utils/set-nested-value.mjs.map +1 -1
- package/build-types/actions.d.ts.map +1 -1
- package/build-types/entities.d.ts.map +1 -1
- package/build-types/hooks/use-entity-record.d.ts +4 -0
- package/build-types/hooks/use-entity-record.d.ts.map +1 -1
- package/build-types/hooks/use-entity-records.d.ts +5 -1
- package/build-types/hooks/use-entity-records.d.ts.map +1 -1
- package/build-types/hooks/utils.d.ts +22 -0
- package/build-types/hooks/utils.d.ts.map +1 -0
- package/build-types/index.d.ts +8 -8
- package/build-types/private-actions.d.ts.map +1 -1
- package/build-types/reducer.d.ts.map +1 -1
- package/build-types/selectors.d.ts +8 -8
- package/build-types/selectors.d.ts.map +1 -1
- package/build-types/utils/clear-unchanged-edits.d.ts +12 -0
- package/build-types/utils/clear-unchanged-edits.d.ts.map +1 -0
- package/build-types/utils/index.d.ts +1 -0
- package/build-types/utils/index.d.ts.map +1 -1
- package/package.json +24 -19
- package/src/actions.js +2 -10
- package/src/entities.js +5 -0
- package/src/hooks/test/use-entity-record.js +5 -1
- package/src/hooks/use-entity-record.ts +26 -19
- package/src/hooks/use-entity-records.ts +26 -18
- package/src/hooks/use-query-select.ts +2 -23
- package/src/hooks/utils.ts +40 -0
- package/src/reducer.js +13 -9
- package/src/test/entities.js +51 -0
- package/src/utils/clear-unchanged-edits.ts +34 -0
- package/src/utils/index.js +1 -0
- package/src/utils/test/clear-unchanged-edits.js +42 -0
- package/build-types/utils/on-sub-key.d.ts +0 -4
- package/build-types/utils/on-sub-key.d.ts.map +0 -1
|
@@ -7,7 +7,7 @@ import { useSelect } from '@wordpress/data';
|
|
|
7
7
|
* Internal dependencies
|
|
8
8
|
*/
|
|
9
9
|
import memoize from 'memize';
|
|
10
|
-
import {
|
|
10
|
+
import { getResolutionStatus } from './utils';
|
|
11
11
|
|
|
12
12
|
export const META_SELECTORS = [
|
|
13
13
|
'getIsResolving',
|
|
@@ -114,30 +114,9 @@ const enrichSelectors = memoize( ( ( selectors ) => {
|
|
|
114
114
|
args
|
|
115
115
|
)?.status;
|
|
116
116
|
|
|
117
|
-
let status;
|
|
118
|
-
switch ( resolutionStatus ) {
|
|
119
|
-
case 'resolving':
|
|
120
|
-
status = Status.Resolving;
|
|
121
|
-
break;
|
|
122
|
-
case 'finished':
|
|
123
|
-
status = Status.Success;
|
|
124
|
-
break;
|
|
125
|
-
case 'error':
|
|
126
|
-
status = Status.Error;
|
|
127
|
-
break;
|
|
128
|
-
case undefined:
|
|
129
|
-
status = Status.Idle;
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
117
|
return {
|
|
134
118
|
data,
|
|
135
|
-
|
|
136
|
-
isResolving: status === Status.Resolving,
|
|
137
|
-
hasStarted: status !== Status.Idle,
|
|
138
|
-
hasResolved:
|
|
139
|
-
status === Status.Success ||
|
|
140
|
-
status === Status.Error,
|
|
119
|
+
...getResolutionStatus( resolutionStatus ),
|
|
141
120
|
};
|
|
142
121
|
},
|
|
143
122
|
} );
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { ResolutionStatus } from '@wordpress/data';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { Status } from './constants';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Normalizes a resolution status from the store into the resolution info
|
|
13
|
+
* shared by the entity record hooks and `useQuerySelect`.
|
|
14
|
+
*
|
|
15
|
+
* @param resolutionStatus Status returned by the `getResolutionState` selector.
|
|
16
|
+
* @return Resolution info object.
|
|
17
|
+
*/
|
|
18
|
+
export function getResolutionStatus( resolutionStatus?: ResolutionStatus ) {
|
|
19
|
+
let status: Status;
|
|
20
|
+
switch ( resolutionStatus ) {
|
|
21
|
+
case 'resolving':
|
|
22
|
+
status = Status.Resolving;
|
|
23
|
+
break;
|
|
24
|
+
case 'finished':
|
|
25
|
+
status = Status.Success;
|
|
26
|
+
break;
|
|
27
|
+
case 'error':
|
|
28
|
+
status = Status.Error;
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
status = Status.Idle;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
status,
|
|
36
|
+
isResolving: status === Status.Resolving,
|
|
37
|
+
hasStarted: status !== Status.Idle,
|
|
38
|
+
hasResolved: status === Status.Success || status === Status.Error,
|
|
39
|
+
};
|
|
40
|
+
}
|
package/src/reducer.js
CHANGED
|
@@ -13,7 +13,7 @@ import { createUndoManager } from '@wordpress/undo-manager';
|
|
|
13
13
|
/**
|
|
14
14
|
* Internal dependencies
|
|
15
15
|
*/
|
|
16
|
-
import { ifMatchingAction, replaceAction } from './utils';
|
|
16
|
+
import { clearUnchangedEdits, ifMatchingAction, replaceAction } from './utils';
|
|
17
17
|
import { reducer as queriedDataReducer } from './queried-data';
|
|
18
18
|
import { rootEntitiesConfig, DEFAULT_ENTITY_KEY } from './entities';
|
|
19
19
|
import { ConnectionErrorCode } from './sync';
|
|
@@ -150,19 +150,23 @@ const withMultiEntityRecordEdits = ( reducer ) => ( state, action ) => {
|
|
|
150
150
|
|
|
151
151
|
let newState = state;
|
|
152
152
|
record.forEach( ( { id: { kind, name, recordId }, changes } ) => {
|
|
153
|
+
const persistedRecord =
|
|
154
|
+
state?.queriedData?.items?.default?.[ recordId ];
|
|
155
|
+
const edits = Object.fromEntries(
|
|
156
|
+
Object.entries( changes ).map( ( [ key, value ] ) => [
|
|
157
|
+
key,
|
|
158
|
+
action.type === 'UNDO' ? value.from : value.to,
|
|
159
|
+
] )
|
|
160
|
+
);
|
|
161
|
+
|
|
153
162
|
newState = reducer( newState, {
|
|
154
163
|
type: 'EDIT_ENTITY_RECORD',
|
|
155
164
|
kind,
|
|
156
165
|
name,
|
|
157
166
|
recordId,
|
|
158
|
-
edits
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
action.type === 'UNDO' ? value.from : value.to;
|
|
162
|
-
return acc;
|
|
163
|
-
},
|
|
164
|
-
{}
|
|
165
|
-
),
|
|
167
|
+
// Clear edits matching the persisted record so the entity is
|
|
168
|
+
// no longer dirty after undoing back to its saved state.
|
|
169
|
+
edits: clearUnchangedEdits( edits, persistedRecord ),
|
|
166
170
|
} );
|
|
167
171
|
} );
|
|
168
172
|
return newState;
|
package/src/test/entities.js
CHANGED
|
@@ -136,15 +136,20 @@ describe( 'prePersistPostType', () => {
|
|
|
136
136
|
|
|
137
137
|
describe( 'loadPostTypeEntities', () => {
|
|
138
138
|
let originalCollaborationEnabled;
|
|
139
|
+
let originalCollaborationDisabledPostTypes;
|
|
139
140
|
|
|
140
141
|
beforeEach( () => {
|
|
141
142
|
apiFetch.mockReset();
|
|
142
143
|
applyPostChangesToCRDTDoc.mockReset();
|
|
143
144
|
originalCollaborationEnabled = window._wpCollaborationEnabled;
|
|
145
|
+
originalCollaborationDisabledPostTypes =
|
|
146
|
+
window._wpCollaborationDisabledPostTypes;
|
|
144
147
|
} );
|
|
145
148
|
|
|
146
149
|
afterEach( () => {
|
|
147
150
|
window._wpCollaborationEnabled = originalCollaborationEnabled;
|
|
151
|
+
window._wpCollaborationDisabledPostTypes =
|
|
152
|
+
originalCollaborationDisabledPostTypes;
|
|
148
153
|
} );
|
|
149
154
|
|
|
150
155
|
it( 'should include custom taxonomy rest_bases in synced properties when collaboration is enabled', async () => {
|
|
@@ -224,6 +229,52 @@ describe( 'loadPostTypeEntities', () => {
|
|
|
224
229
|
expect( syncedProperties ).not.toContain( 'tags' );
|
|
225
230
|
} );
|
|
226
231
|
|
|
232
|
+
it( 'should sync post type entities by default', async () => {
|
|
233
|
+
window._wpCollaborationEnabled = false;
|
|
234
|
+
window._wpCollaborationDisabledPostTypes = undefined;
|
|
235
|
+
|
|
236
|
+
const mockPostTypes = {
|
|
237
|
+
post: {
|
|
238
|
+
name: 'Posts',
|
|
239
|
+
rest_base: 'posts',
|
|
240
|
+
rest_namespace: 'wp/v2',
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
apiFetch.mockResolvedValueOnce( mockPostTypes );
|
|
245
|
+
|
|
246
|
+
const postTypeLoader = additionalEntityConfigLoaders.find(
|
|
247
|
+
( loader ) => loader.kind === 'postType'
|
|
248
|
+
);
|
|
249
|
+
const entities = await postTypeLoader.loadEntities();
|
|
250
|
+
const postEntity = entities.find( ( e ) => e.name === 'post' );
|
|
251
|
+
|
|
252
|
+
expect( postEntity.syncConfig.shouldSync() ).toBe( true );
|
|
253
|
+
} );
|
|
254
|
+
|
|
255
|
+
it( 'should not sync post type entities disabled for collaboration', async () => {
|
|
256
|
+
window._wpCollaborationEnabled = false;
|
|
257
|
+
window._wpCollaborationDisabledPostTypes = [ 'book' ];
|
|
258
|
+
|
|
259
|
+
const mockPostTypes = {
|
|
260
|
+
book: {
|
|
261
|
+
name: 'Books',
|
|
262
|
+
rest_base: 'books',
|
|
263
|
+
rest_namespace: 'wp/v2',
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
apiFetch.mockResolvedValueOnce( mockPostTypes );
|
|
268
|
+
|
|
269
|
+
const postTypeLoader = additionalEntityConfigLoaders.find(
|
|
270
|
+
( loader ) => loader.kind === 'postType'
|
|
271
|
+
);
|
|
272
|
+
const entities = await postTypeLoader.loadEntities();
|
|
273
|
+
const bookEntity = entities.find( ( e ) => e.name === 'book' );
|
|
274
|
+
|
|
275
|
+
expect( bookEntity.syncConfig.shouldSync() ).toBe( false );
|
|
276
|
+
} );
|
|
277
|
+
|
|
227
278
|
it( 'should skip taxonomy rest_base when taxonomy is not found in fetched taxonomies', async () => {
|
|
228
279
|
window._wpCollaborationEnabled = true;
|
|
229
280
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import fastDeepEqual from 'fast-deep-equal/es6/index.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Returns a copy of `edits` where any value equal to its persisted counterpart
|
|
8
|
+
* is set to `undefined`. The edits reducer treats `undefined` as a signal to
|
|
9
|
+
* drop the edit, so the property is no longer considered dirty.
|
|
10
|
+
*
|
|
11
|
+
* @param edits Edits keyed by property name.
|
|
12
|
+
* @param persistedRecord Persisted entity record to compare against.
|
|
13
|
+
*
|
|
14
|
+
* @return Edits with unchanged properties set to `undefined`.
|
|
15
|
+
*/
|
|
16
|
+
export default function clearUnchangedEdits(
|
|
17
|
+
edits: Record< string, unknown >,
|
|
18
|
+
persistedRecord: Record< string, any > | undefined
|
|
19
|
+
): Record< string, unknown > {
|
|
20
|
+
if ( ! persistedRecord ) {
|
|
21
|
+
return edits;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return Object.fromEntries(
|
|
25
|
+
Object.entries( edits ).map( ( [ key, value ] ) => {
|
|
26
|
+
const persisted =
|
|
27
|
+
persistedRecord[ key ]?.raw ?? persistedRecord[ key ];
|
|
28
|
+
return [
|
|
29
|
+
key,
|
|
30
|
+
fastDeepEqual( value, persisted ) ? undefined : value,
|
|
31
|
+
];
|
|
32
|
+
} )
|
|
33
|
+
);
|
|
34
|
+
}
|
package/src/utils/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { default as clearUnchangedEdits } from './clear-unchanged-edits';
|
|
1
2
|
export { default as conservativeMapItem } from './conservative-map-item';
|
|
2
3
|
export { default as getNormalizedCommaSeparable } from './get-normalized-comma-separable';
|
|
3
4
|
export { default as ifMatchingAction } from './if-matching-action';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import clearUnchangedEdits from '../clear-unchanged-edits';
|
|
5
|
+
|
|
6
|
+
describe( 'clearUnchangedEdits', () => {
|
|
7
|
+
it( 'sets edits matching the persisted record to undefined', () => {
|
|
8
|
+
const result = clearUnchangedEdits(
|
|
9
|
+
{ title: 'Hello', status: 'draft' },
|
|
10
|
+
{ title: 'Hello', status: 'publish' }
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
expect( result ).toEqual( { title: undefined, status: 'draft' } );
|
|
14
|
+
} );
|
|
15
|
+
|
|
16
|
+
it( 'unwraps the persisted value from its `raw` subfield', () => {
|
|
17
|
+
const result = clearUnchangedEdits(
|
|
18
|
+
{ title: 'Hello', content: 'World' },
|
|
19
|
+
{
|
|
20
|
+
title: { raw: 'Hello', rendered: '<p>Hello</p>' },
|
|
21
|
+
content: { raw: 'Changed', rendered: '<p>Changed</p>' },
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
expect( result ).toEqual( { title: undefined, content: 'World' } );
|
|
26
|
+
} );
|
|
27
|
+
|
|
28
|
+
it( 'compares deeply for object values', () => {
|
|
29
|
+
const result = clearUnchangedEdits(
|
|
30
|
+
{ meta: { a: 1 }, other: { b: 1 } },
|
|
31
|
+
{ meta: { a: 1 }, other: { b: 2 } }
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect( result ).toEqual( { meta: undefined, other: { b: 1 } } );
|
|
35
|
+
} );
|
|
36
|
+
|
|
37
|
+
it( 'keeps all edits when there is no persisted record', () => {
|
|
38
|
+
const result = clearUnchangedEdits( { title: 'Hello' }, undefined );
|
|
39
|
+
|
|
40
|
+
expect( result ).toEqual( { title: 'Hello' } );
|
|
41
|
+
} );
|
|
42
|
+
} );
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"on-sub-key.d.ts","sourceRoot":"","sources":["../../src/utils/on-sub-key.js"],"names":[],"mappings":"AAUO,yCAJI,MAAM,GAEL,WAAW,CAwBrB;;0BAhCY,OAAO,UAAU,EAAE,WAAW"}
|