@wordpress/core-data 7.40.2-next.v.202602271551.0 → 7.40.2
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 +0 -27
- package/build/actions.cjs +9 -26
- package/build/actions.cjs.map +2 -2
- package/build/awareness/post-editor-awareness.cjs +45 -6
- package/build/awareness/post-editor-awareness.cjs.map +2 -2
- package/build/awareness/types.cjs.map +1 -1
- package/build/entities.cjs +36 -16
- package/build/entities.cjs.map +2 -2
- package/build/entity-provider.cjs +15 -6
- package/build/entity-provider.cjs.map +2 -2
- package/build/hooks/use-entity-prop.cjs +33 -2
- package/build/hooks/use-entity-prop.cjs.map +2 -2
- package/build/hooks/use-post-editor-awareness-state.cjs +120 -1
- package/build/hooks/use-post-editor-awareness-state.cjs.map +2 -2
- package/build/index.cjs +0 -3
- package/build/index.cjs.map +2 -2
- package/build/private-actions.cjs +27 -3
- package/build/private-actions.cjs.map +2 -2
- package/build/private-apis.cjs +14 -5
- package/build/private-apis.cjs.map +3 -3
- package/build/private-selectors.cjs +22 -2
- package/build/private-selectors.cjs.map +2 -2
- package/build/queried-data/actions.cjs +1 -1
- package/build/queried-data/actions.cjs.map +2 -2
- package/build/queried-data/reducer.cjs +19 -13
- package/build/queried-data/reducer.cjs.map +2 -2
- package/build/reducer.cjs +19 -2
- package/build/reducer.cjs.map +2 -2
- package/build/resolvers.cjs +24 -17
- package/build/resolvers.cjs.map +2 -2
- package/build/selectors.cjs +0 -15
- package/build/selectors.cjs.map +2 -2
- package/build/sync.cjs +12 -3
- package/build/sync.cjs.map +2 -2
- package/build/types.cjs.map +1 -1
- package/build/utils/block-selection-history.cjs +1 -1
- package/build/utils/block-selection-history.cjs.map +2 -2
- package/build/utils/crdt-blocks.cjs +85 -28
- package/build/utils/crdt-blocks.cjs.map +2 -2
- package/build/utils/crdt-selection.cjs +4 -1
- package/build/utils/crdt-selection.cjs.map +2 -2
- package/build/utils/crdt-text.cjs +52 -0
- package/build/utils/crdt-text.cjs.map +7 -0
- package/build/utils/crdt-user-selections.cjs +16 -6
- package/build/utils/crdt-user-selections.cjs.map +3 -3
- package/build/utils/crdt-utils.cjs +54 -2
- package/build/utils/crdt-utils.cjs.map +2 -2
- package/build/utils/crdt.cjs +26 -28
- package/build/utils/crdt.cjs.map +2 -2
- package/build-module/actions.mjs +14 -26
- package/build-module/actions.mjs.map +2 -2
- package/build-module/awareness/post-editor-awareness.mjs +47 -7
- package/build-module/awareness/post-editor-awareness.mjs.map +2 -2
- package/build-module/entities.mjs +37 -16
- package/build-module/entities.mjs.map +2 -2
- package/build-module/entity-provider.mjs +15 -6
- package/build-module/entity-provider.mjs.map +2 -2
- package/build-module/hooks/use-entity-prop.mjs +34 -3
- package/build-module/hooks/use-entity-prop.mjs.map +2 -2
- package/build-module/hooks/use-post-editor-awareness-state.mjs +117 -1
- package/build-module/hooks/use-post-editor-awareness-state.mjs.map +2 -2
- package/build-module/index.mjs +0 -2
- package/build-module/index.mjs.map +2 -2
- package/build-module/private-actions.mjs +24 -2
- package/build-module/private-actions.mjs.map +2 -2
- package/build-module/private-apis.mjs +21 -6
- package/build-module/private-apis.mjs.map +3 -3
- package/build-module/private-selectors.mjs +19 -1
- package/build-module/private-selectors.mjs.map +2 -2
- package/build-module/queried-data/actions.mjs +1 -1
- package/build-module/queried-data/actions.mjs.map +2 -2
- package/build-module/queried-data/reducer.mjs +19 -13
- package/build-module/queried-data/reducer.mjs.map +2 -2
- package/build-module/reducer.mjs +18 -2
- package/build-module/reducer.mjs.map +2 -2
- package/build-module/resolvers.mjs +24 -17
- package/build-module/resolvers.mjs.map +2 -2
- package/build-module/selectors.mjs +0 -14
- package/build-module/selectors.mjs.map +2 -2
- package/build-module/sync.mjs +8 -2
- package/build-module/sync.mjs.map +2 -2
- package/build-module/utils/block-selection-history.mjs +5 -2
- package/build-module/utils/block-selection-history.mjs.map +2 -2
- package/build-module/utils/crdt-blocks.mjs +84 -28
- package/build-module/utils/crdt-blocks.mjs.map +2 -2
- package/build-module/utils/crdt-selection.mjs +8 -2
- package/build-module/utils/crdt-selection.mjs.map +2 -2
- package/build-module/utils/crdt-text.mjs +26 -0
- package/build-module/utils/crdt-text.mjs.map +7 -0
- package/build-module/utils/crdt-user-selections.mjs +16 -7
- package/build-module/utils/crdt-user-selections.mjs.map +3 -3
- package/build-module/utils/crdt-utils.mjs +51 -1
- package/build-module/utils/crdt-utils.mjs.map +2 -2
- package/build-module/utils/crdt.mjs +26 -28
- package/build-module/utils/crdt.mjs.map +2 -2
- package/build-types/actions.d.ts +0 -11
- package/build-types/actions.d.ts.map +1 -1
- package/build-types/awareness/post-editor-awareness.d.ts +2 -2
- package/build-types/awareness/post-editor-awareness.d.ts.map +1 -1
- package/build-types/awareness/types.d.ts +6 -1
- package/build-types/awareness/types.d.ts.map +1 -1
- package/build-types/entities.d.ts +20 -1
- package/build-types/entities.d.ts.map +1 -1
- package/build-types/entity-provider.d.ts +11 -6
- package/build-types/entity-provider.d.ts.map +1 -1
- package/build-types/hooks/use-entity-prop.d.ts.map +1 -1
- package/build-types/hooks/use-post-editor-awareness-state.d.ts +40 -7
- package/build-types/hooks/use-post-editor-awareness-state.d.ts.map +1 -1
- package/build-types/index.d.ts +0 -3
- package/build-types/index.d.ts.map +1 -1
- package/build-types/parsed-blocks-cache.d.ts +10 -0
- package/build-types/parsed-blocks-cache.d.ts.map +1 -0
- package/build-types/private-actions.d.ts +12 -0
- package/build-types/private-actions.d.ts.map +1 -1
- package/build-types/private-apis.d.ts +21 -1
- package/build-types/private-apis.d.ts.map +1 -1
- package/build-types/private-selectors.d.ts +17 -0
- package/build-types/private-selectors.d.ts.map +1 -1
- package/build-types/queried-data/reducer.d.ts.map +1 -1
- package/build-types/reducer.d.ts +15 -0
- package/build-types/reducer.d.ts.map +1 -1
- package/build-types/resolvers.d.ts.map +1 -1
- package/build-types/selectors.d.ts +1 -9
- package/build-types/selectors.d.ts.map +1 -1
- package/build-types/sync.d.ts +2 -2
- package/build-types/sync.d.ts.map +1 -1
- package/build-types/types.d.ts +10 -2
- package/build-types/types.d.ts.map +1 -1
- package/build-types/utils/block-selection-history.d.ts.map +1 -1
- package/build-types/utils/crdt-blocks.d.ts +11 -0
- package/build-types/utils/crdt-blocks.d.ts.map +1 -1
- package/build-types/utils/crdt-selection.d.ts.map +1 -1
- package/build-types/utils/crdt-text.d.ts +16 -0
- package/build-types/utils/crdt-text.d.ts.map +1 -0
- package/build-types/utils/crdt-user-selections.d.ts +17 -4
- package/build-types/utils/crdt-user-selections.d.ts.map +1 -1
- package/build-types/utils/crdt-utils.d.ts +20 -0
- package/build-types/utils/crdt-utils.d.ts.map +1 -1
- package/build-types/utils/crdt.d.ts +13 -7
- package/build-types/utils/crdt.d.ts.map +1 -1
- package/build-types/utils/normalize-query-for-resolution.d.ts +12 -0
- package/build-types/utils/normalize-query-for-resolution.d.ts.map +1 -0
- package/build-types/utils/save-crdt-doc.d.ts +8 -0
- package/build-types/utils/save-crdt-doc.d.ts.map +1 -0
- package/build-types/utils/test/crdt-utils.d.ts +2 -0
- package/build-types/utils/test/crdt-utils.d.ts.map +1 -0
- package/package.json +18 -18
- package/src/actions.js +26 -41
- package/src/awareness/post-editor-awareness.ts +106 -7
- package/src/awareness/test/post-editor-awareness.ts +50 -10
- package/src/awareness/types.ts +7 -1
- package/src/entities.js +43 -17
- package/src/entity-provider.js +24 -11
- package/src/hooks/test/use-post-editor-awareness-state.ts +446 -3
- package/src/hooks/use-entity-prop.js +43 -3
- package/src/hooks/use-post-editor-awareness-state.ts +229 -7
- package/src/index.js +0 -6
- package/src/private-actions.js +43 -1
- package/src/{private-apis.js → private-apis.ts} +21 -3
- package/src/private-selectors.ts +43 -0
- package/src/queried-data/actions.js +1 -1
- package/src/queried-data/reducer.js +26 -14
- package/src/reducer.js +36 -1
- package/src/resolvers.js +33 -23
- package/src/selectors.ts +1 -32
- package/src/sync.ts +6 -0
- package/src/test/entities.js +204 -16
- package/src/test/private-actions.js +1 -1
- package/src/test/resolvers.js +144 -57
- package/src/test/store.js +116 -0
- package/src/types.ts +20 -2
- package/src/utils/block-selection-history.ts +5 -2
- package/src/utils/crdt-blocks.ts +159 -56
- package/src/utils/crdt-selection.ts +8 -2
- package/src/utils/crdt-text.ts +43 -0
- package/src/utils/crdt-user-selections.ts +29 -8
- package/src/utils/crdt-utils.ts +99 -0
- package/src/utils/crdt.ts +50 -40
- package/src/utils/test/crdt-blocks.ts +588 -24
- package/src/utils/test/crdt-user-selections.ts +5 -0
- package/src/utils/test/crdt-utils.ts +387 -0
- package/src/utils/test/crdt.ts +291 -54
package/src/utils/crdt-utils.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { Y } from '@wordpress/sync';
|
|
5
|
+
import { create, insert, toHTMLString } from '@wordpress/rich-text';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Internal dependencies
|
|
@@ -104,6 +105,104 @@ export function findBlockByClientIdInDoc(
|
|
|
104
105
|
return findBlockByClientIdInBlocks( blockId, blocks );
|
|
105
106
|
}
|
|
106
107
|
|
|
108
|
+
// Marker for insertion.
|
|
109
|
+
const MARKER_START = 0xe000;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Pick a marker character that does not appear in `text`. Returns the marker
|
|
113
|
+
* or `null` if all candidates are present (extremely unlikely in practice).
|
|
114
|
+
*
|
|
115
|
+
* @param text The string to check for existing marker characters.
|
|
116
|
+
*/
|
|
117
|
+
function pickMarker( text: string ): string | null {
|
|
118
|
+
const tryCount = 0x10;
|
|
119
|
+
|
|
120
|
+
// Scan the unicode private use area for the first code point not present
|
|
121
|
+
// in the text.
|
|
122
|
+
for ( let code = MARKER_START; code < MARKER_START + tryCount; code++ ) {
|
|
123
|
+
const candidate = String.fromCharCode( code );
|
|
124
|
+
|
|
125
|
+
if ( ! text.includes( candidate ) ) {
|
|
126
|
+
return candidate;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Convert an HTML character index (counting tag characters) to a rich-text
|
|
135
|
+
* offset (counting only text characters). Used on read paths where Y.Text
|
|
136
|
+
* resolves to an HTML index but the block editor expects a text offset.
|
|
137
|
+
*
|
|
138
|
+
* @param html The full HTML string from Y.Text.
|
|
139
|
+
* @param htmlIndex The HTML character index.
|
|
140
|
+
* @return The corresponding rich-text offset.
|
|
141
|
+
*/
|
|
142
|
+
export function htmlIndexToRichTextOffset(
|
|
143
|
+
html: string,
|
|
144
|
+
htmlIndex: number
|
|
145
|
+
): number {
|
|
146
|
+
if ( ! html.includes( '<' ) && ! html.includes( '&' ) ) {
|
|
147
|
+
return htmlIndex;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const marker = pickMarker( html );
|
|
151
|
+
if ( ! marker ) {
|
|
152
|
+
return htmlIndex;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Insert marker and let create() do the parsing.
|
|
156
|
+
const withMarker =
|
|
157
|
+
html.slice( 0, htmlIndex ) + marker + html.slice( htmlIndex );
|
|
158
|
+
const value = create( { html: withMarker } );
|
|
159
|
+
const markerPos = value.text.indexOf( marker );
|
|
160
|
+
|
|
161
|
+
return markerPos === -1 ? htmlIndex : markerPos;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Convert a rich-text offset (counting only text characters) to an HTML
|
|
166
|
+
* character index (counting tag characters). Used on write paths where the
|
|
167
|
+
* block editor provides a text offset but Y.Text expects an HTML index.
|
|
168
|
+
*
|
|
169
|
+
* @param html The full HTML string from Y.Text.
|
|
170
|
+
* @param richTextOffset The rich-text text offset.
|
|
171
|
+
* @return The corresponding HTML character index.
|
|
172
|
+
*/
|
|
173
|
+
export function richTextOffsetToHtmlIndex(
|
|
174
|
+
html: string,
|
|
175
|
+
richTextOffset: number
|
|
176
|
+
): number {
|
|
177
|
+
if ( ! html.includes( '<' ) && ! html.includes( '&' ) ) {
|
|
178
|
+
return richTextOffset;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const marker = pickMarker( html );
|
|
182
|
+
if ( ! marker ) {
|
|
183
|
+
return richTextOffset;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const value = create( { html } );
|
|
187
|
+
const markerValue = create( { text: marker } );
|
|
188
|
+
// The marker must inherit the formatting at the insertion point so that
|
|
189
|
+
// toHTMLString does not split surrounding tags (e.g. <strong>) around it.
|
|
190
|
+
if ( value.formats[ richTextOffset ] ) {
|
|
191
|
+
markerValue.formats[ 0 ] = value.formats[ richTextOffset ];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const withMarker = insert(
|
|
195
|
+
value,
|
|
196
|
+
markerValue,
|
|
197
|
+
richTextOffset,
|
|
198
|
+
richTextOffset
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const htmlWithMarker = toHTMLString( { value: withMarker } );
|
|
202
|
+
const markerIndex = htmlWithMarker.indexOf( marker );
|
|
203
|
+
return markerIndex === -1 ? richTextOffset : markerIndex;
|
|
204
|
+
}
|
|
205
|
+
|
|
107
206
|
function findBlockByClientIdInBlocks(
|
|
108
207
|
blockId: string,
|
|
109
208
|
blocks: YBlocks
|
package/src/utils/crdt.ts
CHANGED
|
@@ -11,6 +11,8 @@ import { __unstableSerializeAndClean } from '@wordpress/blocks';
|
|
|
11
11
|
import {
|
|
12
12
|
type CRDTDoc,
|
|
13
13
|
type ObjectData,
|
|
14
|
+
type ObjectID,
|
|
15
|
+
type ObjectType,
|
|
14
16
|
type SyncConfig,
|
|
15
17
|
Y,
|
|
16
18
|
} from '@wordpress/sync';
|
|
@@ -20,6 +22,7 @@ import {
|
|
|
20
22
|
*/
|
|
21
23
|
import { BaseAwareness } from '../awareness/base-awareness';
|
|
22
24
|
import {
|
|
25
|
+
deserializeBlockAttributes,
|
|
23
26
|
mergeCrdtBlocks,
|
|
24
27
|
mergeRichTextUpdate,
|
|
25
28
|
type Block,
|
|
@@ -27,7 +30,6 @@ import {
|
|
|
27
30
|
type YBlocks,
|
|
28
31
|
} from './crdt-blocks';
|
|
29
32
|
import { type Post } from '../entity-types/post';
|
|
30
|
-
import { type Type } from '../entity-types';
|
|
31
33
|
import { CRDT_DOC_META_PERSISTENCE_KEY, CRDT_RECORD_MAP_KEY } from '../sync';
|
|
32
34
|
import type { WPSelection } from '../types';
|
|
33
35
|
import {
|
|
@@ -76,27 +78,6 @@ export interface YPostRecord extends YMapRecord {
|
|
|
76
78
|
|
|
77
79
|
export const POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE = '_crdt_document';
|
|
78
80
|
|
|
79
|
-
// Properties that are allowed to be synced for a post.
|
|
80
|
-
const allowedPostProperties = new Set< string >( [
|
|
81
|
-
'author',
|
|
82
|
-
'blocks',
|
|
83
|
-
'content',
|
|
84
|
-
'categories',
|
|
85
|
-
'comment_status',
|
|
86
|
-
'date',
|
|
87
|
-
'excerpt',
|
|
88
|
-
'featured_media',
|
|
89
|
-
'format',
|
|
90
|
-
'meta',
|
|
91
|
-
'ping_status',
|
|
92
|
-
'slug',
|
|
93
|
-
'status',
|
|
94
|
-
'sticky',
|
|
95
|
-
'tags',
|
|
96
|
-
'template',
|
|
97
|
-
'title',
|
|
98
|
-
] );
|
|
99
|
-
|
|
100
81
|
// Post meta keys that should *not* be synced.
|
|
101
82
|
const disallowedPostMetaKeys = new Set< string >( [
|
|
102
83
|
POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE,
|
|
@@ -139,18 +120,18 @@ function defaultApplyChangesToCRDTDoc(
|
|
|
139
120
|
*
|
|
140
121
|
* @param {CRDTDoc} ydoc
|
|
141
122
|
* @param {PostChanges} changes
|
|
142
|
-
* @param {
|
|
123
|
+
* @param {Set<string>} syncedProperties
|
|
143
124
|
* @return {void}
|
|
144
125
|
*/
|
|
145
126
|
export function applyPostChangesToCRDTDoc(
|
|
146
127
|
ydoc: CRDTDoc,
|
|
147
128
|
changes: PostChanges,
|
|
148
|
-
|
|
129
|
+
syncedProperties: Set< string >
|
|
149
130
|
): void {
|
|
150
131
|
const ymap = getRootMap< YPostRecord >( ydoc, CRDT_RECORD_MAP_KEY );
|
|
151
132
|
|
|
152
133
|
Object.keys( changes ).forEach( ( key ) => {
|
|
153
|
-
if ( !
|
|
134
|
+
if ( ! syncedProperties.has( key ) ) {
|
|
154
135
|
return;
|
|
155
136
|
}
|
|
156
137
|
|
|
@@ -289,15 +270,15 @@ function defaultGetChangesFromCRDTDoc( crdtDoc: CRDTDoc ): ObjectData {
|
|
|
289
270
|
* against the local record and determine if there are changes (edits) we want
|
|
290
271
|
* to dispatch.
|
|
291
272
|
*
|
|
292
|
-
* @param {CRDTDoc}
|
|
293
|
-
* @param {Post}
|
|
294
|
-
* @param {
|
|
273
|
+
* @param {CRDTDoc} ydoc
|
|
274
|
+
* @param {Post} editedRecord
|
|
275
|
+
* @param {Set<string>} syncedProperties
|
|
295
276
|
* @return {Partial<PostChanges>} The changes that should be applied to the local record.
|
|
296
277
|
*/
|
|
297
278
|
export function getPostChangesFromCRDTDoc(
|
|
298
279
|
ydoc: CRDTDoc,
|
|
299
280
|
editedRecord: Post,
|
|
300
|
-
|
|
281
|
+
syncedProperties: Set< string >
|
|
301
282
|
): PostChanges {
|
|
302
283
|
const ymap = getRootMap< YPostRecord >( ydoc, CRDT_RECORD_MAP_KEY );
|
|
303
284
|
|
|
@@ -305,7 +286,7 @@ export function getPostChangesFromCRDTDoc(
|
|
|
305
286
|
|
|
306
287
|
const changes = Object.fromEntries(
|
|
307
288
|
Object.entries( ymap.toJSON() ).filter( ( [ key, newValue ] ) => {
|
|
308
|
-
if ( !
|
|
289
|
+
if ( ! syncedProperties.has( key ) ) {
|
|
309
290
|
return false;
|
|
310
291
|
}
|
|
311
292
|
|
|
@@ -342,8 +323,6 @@ export function getPostChangesFromCRDTDoc(
|
|
|
342
323
|
);
|
|
343
324
|
}
|
|
344
325
|
|
|
345
|
-
// The consumers of blocks have memoization that renders optimization
|
|
346
|
-
// here unnecessary.
|
|
347
326
|
return true;
|
|
348
327
|
}
|
|
349
328
|
|
|
@@ -351,11 +330,8 @@ export function getPostChangesFromCRDTDoc(
|
|
|
351
330
|
// Do not overwrite a "floating" date. Borrowing logic from the
|
|
352
331
|
// isEditedPostDateFloating selector.
|
|
353
332
|
const currentDateIsFloating =
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
) &&
|
|
357
|
-
( null === currentValue ||
|
|
358
|
-
editedRecord.modified === currentValue );
|
|
333
|
+
null === currentValue ||
|
|
334
|
+
editedRecord.modified === currentValue;
|
|
359
335
|
|
|
360
336
|
if ( currentDateIsFloating ) {
|
|
361
337
|
return false;
|
|
@@ -365,17 +341,29 @@ export function getPostChangesFromCRDTDoc(
|
|
|
365
341
|
}
|
|
366
342
|
|
|
367
343
|
case 'meta': {
|
|
344
|
+
const currentMeta =
|
|
345
|
+
( currentValue as PostChanges[ 'meta' ] ) ?? {};
|
|
346
|
+
|
|
368
347
|
allowedMetaChanges = Object.fromEntries(
|
|
369
348
|
Object.entries( newValue ?? {} ).filter(
|
|
370
|
-
( [ metaKey ] ) =>
|
|
371
|
-
|
|
349
|
+
( [ metaKey ] ) => {
|
|
350
|
+
if ( disallowedPostMetaKeys.has( metaKey ) ) {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Ignore meta keys that are no longer registered
|
|
355
|
+
// for this post (absent from the REST response).
|
|
356
|
+
// Without this, orphaned CRDT meta would mark
|
|
357
|
+
// the post permanently dirty.
|
|
358
|
+
return metaKey in currentMeta;
|
|
359
|
+
}
|
|
372
360
|
)
|
|
373
361
|
);
|
|
374
362
|
|
|
375
363
|
// Merge the allowed meta changes with the current meta values since
|
|
376
364
|
// not all meta properties are synced.
|
|
377
365
|
const mergedValue = {
|
|
378
|
-
...
|
|
366
|
+
...currentMeta,
|
|
379
367
|
...allowedMetaChanges,
|
|
380
368
|
};
|
|
381
369
|
|
|
@@ -409,6 +397,15 @@ export function getPostChangesFromCRDTDoc(
|
|
|
409
397
|
} )
|
|
410
398
|
);
|
|
411
399
|
|
|
400
|
+
// Blocks extracted from the CRDT document have rich-text attributes as
|
|
401
|
+
// plain strings (from Y.Text.toJSON()). Convert them back to RichTextData
|
|
402
|
+
// so block edit components receive the same types as locally-created blocks.
|
|
403
|
+
if ( changes.blocks ) {
|
|
404
|
+
changes.blocks = deserializeBlockAttributes(
|
|
405
|
+
changes.blocks as Block[]
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
|
|
412
409
|
// Meta changes must be merged with the edited record since not all meta
|
|
413
410
|
// properties are synced.
|
|
414
411
|
if ( 'object' === typeof changes.meta ) {
|
|
@@ -445,6 +442,19 @@ export const defaultSyncConfig: SyncConfig = {
|
|
|
445
442
|
getChangesFromCRDTDoc: defaultGetChangesFromCRDTDoc,
|
|
446
443
|
};
|
|
447
444
|
|
|
445
|
+
/**
|
|
446
|
+
* This default collection sync config can be used to sync entity collections
|
|
447
|
+
* (e.g., block comments) where we are not interested in merging changes at the
|
|
448
|
+
* individual record level, but instead want to replace the entire collection
|
|
449
|
+
* when changes are detected.
|
|
450
|
+
*/
|
|
451
|
+
export const defaultCollectionSyncConfig: SyncConfig = {
|
|
452
|
+
applyChangesToCRDTDoc: () => {},
|
|
453
|
+
getChangesFromCRDTDoc: () => ( {} ),
|
|
454
|
+
shouldSync: ( _: ObjectType, objectId: ObjectID | null ) =>
|
|
455
|
+
null === objectId,
|
|
456
|
+
};
|
|
457
|
+
|
|
448
458
|
/**
|
|
449
459
|
* Extract the raw string value from a property that may be a string or an object
|
|
450
460
|
* with a `raw` property (`RenderedText`).
|