@wordpress/core-data 7.40.2-next.v.202602241322.0 → 7.41.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/CHANGELOG.md +2 -0
- package/build/actions.cjs +1 -1
- package/build/actions.cjs.map +2 -2
- package/build/awareness/types.cjs.map +1 -1
- package/build/entities.cjs +17 -10
- package/build/entities.cjs.map +2 -2
- package/build/hooks/use-post-editor-awareness-state.cjs +38 -0
- package/build/hooks/use-post-editor-awareness-state.cjs.map +2 -2
- package/build/private-actions.cjs +7 -2
- package/build/private-actions.cjs.map +2 -2
- package/build/private-apis.cjs +4 -1
- package/build/private-apis.cjs.map +2 -2
- package/build/private-selectors.cjs +7 -2
- package/build/private-selectors.cjs.map +2 -2
- package/build/reducer.cjs +11 -1
- package/build/reducer.cjs.map +2 -2
- package/build/resolvers.cjs +15 -12
- package/build/resolvers.cjs.map +2 -2
- package/build/selectors.cjs.map +2 -2
- package/build/sync.cjs +5 -5
- package/build/sync.cjs.map +1 -1
- package/build/types.cjs.map +1 -1
- package/build/utils/crdt-blocks.cjs +50 -31
- package/build/utils/crdt-blocks.cjs.map +2 -2
- package/build/utils/crdt-selection.cjs +46 -18
- package/build/utils/crdt-selection.cjs.map +2 -2
- package/build/utils/crdt.cjs +12 -1
- package/build/utils/crdt.cjs.map +2 -2
- package/build-module/actions.mjs +1 -1
- package/build-module/actions.mjs.map +2 -2
- package/build-module/entities.mjs +19 -11
- package/build-module/entities.mjs.map +2 -2
- package/build-module/hooks/use-post-editor-awareness-state.mjs +37 -0
- package/build-module/hooks/use-post-editor-awareness-state.mjs.map +2 -2
- package/build-module/private-actions.mjs +5 -1
- package/build-module/private-actions.mjs.map +2 -2
- package/build-module/private-apis.mjs +6 -2
- package/build-module/private-apis.mjs.map +2 -2
- package/build-module/private-selectors.mjs +5 -1
- package/build-module/private-selectors.mjs.map +2 -2
- package/build-module/reducer.mjs +10 -1
- package/build-module/reducer.mjs.map +2 -2
- package/build-module/resolvers.mjs +15 -12
- package/build-module/resolvers.mjs.map +2 -2
- package/build-module/selectors.mjs.map +2 -2
- package/build-module/sync.mjs +3 -3
- package/build-module/sync.mjs.map +1 -1
- package/build-module/utils/crdt-blocks.mjs +50 -31
- package/build-module/utils/crdt-blocks.mjs.map +2 -2
- package/build-module/utils/crdt-selection.mjs +45 -18
- package/build-module/utils/crdt-selection.mjs.map +2 -2
- package/build-module/utils/crdt.mjs +16 -6
- package/build-module/utils/crdt.mjs.map +2 -2
- package/build-types/awareness/types.d.ts +5 -0
- package/build-types/awareness/types.d.ts.map +1 -1
- package/build-types/entities.d.ts +1 -1
- package/build-types/entities.d.ts.map +1 -1
- package/build-types/hooks/use-post-editor-awareness-state.d.ts +10 -1
- package/build-types/hooks/use-post-editor-awareness-state.d.ts.map +1 -1
- package/build-types/index.d.ts.map +1 -1
- package/build-types/private-actions.d.ts +1 -0
- package/build-types/private-actions.d.ts.map +1 -1
- package/build-types/private-apis.d.ts.map +1 -1
- package/build-types/private-selectors.d.ts +7 -0
- package/build-types/private-selectors.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 -0
- 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 +1 -0
- package/build-types/types.d.ts.map +1 -1
- package/build-types/utils/crdt-blocks.d.ts +1 -1
- package/build-types/utils/crdt-blocks.d.ts.map +1 -1
- package/build-types/utils/crdt-selection.d.ts +10 -0
- package/build-types/utils/crdt-selection.d.ts.map +1 -1
- package/build-types/utils/crdt.d.ts +1 -0
- package/build-types/utils/crdt.d.ts.map +1 -1
- package/package.json +18 -18
- package/src/actions.js +2 -2
- package/src/awareness/types.ts +6 -0
- package/src/entities.js +23 -11
- package/src/hooks/use-post-editor-awareness-state.ts +70 -0
- package/src/private-actions.js +13 -0
- package/src/private-apis.js +4 -0
- package/src/private-selectors.ts +10 -0
- package/src/reducer.js +21 -0
- package/src/resolvers.js +21 -15
- package/src/selectors.ts +1 -0
- package/src/sync.ts +2 -2
- package/src/test/entities.js +47 -14
- package/src/test/resolvers.js +46 -80
- package/src/types.ts +1 -0
- package/src/utils/crdt-blocks.ts +113 -47
- package/src/utils/crdt-selection.ts +84 -24
- package/src/utils/crdt.ts +23 -7
- package/src/utils/test/crdt-blocks.ts +938 -0
- package/src/utils/test/crdt.ts +136 -10
package/src/utils/test/crdt.ts
CHANGED
|
@@ -11,17 +11,16 @@ import { describe, expect, it, jest, beforeEach } from '@jest/globals';
|
|
|
11
11
|
/**
|
|
12
12
|
* Internal dependencies
|
|
13
13
|
*/
|
|
14
|
-
import {
|
|
15
|
-
CRDT_RECORD_MAP_KEY,
|
|
16
|
-
WORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE,
|
|
17
|
-
} from '../../sync';
|
|
14
|
+
import { CRDT_RECORD_MAP_KEY } from '../../sync';
|
|
18
15
|
import {
|
|
19
16
|
applyPostChangesToCRDTDoc,
|
|
20
17
|
getPostChangesFromCRDTDoc,
|
|
18
|
+
POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE,
|
|
21
19
|
type PostChanges,
|
|
22
20
|
type YPostRecord,
|
|
23
21
|
} from '../crdt';
|
|
24
|
-
import type { YBlock, YBlocks } from '../crdt-blocks';
|
|
22
|
+
import type { YBlock, YBlockRecord, YBlocks } from '../crdt-blocks';
|
|
23
|
+
import { updateSelectionHistory } from '../crdt-selection';
|
|
25
24
|
import { createYMap, getRootMap, type YMapWrap } from '../crdt-utils';
|
|
26
25
|
import type { Post, Type } from '../../entity-types';
|
|
27
26
|
|
|
@@ -604,10 +603,7 @@ describe( 'crdt', () => {
|
|
|
604
603
|
it( 'excludes disallowed meta keys in changes', () => {
|
|
605
604
|
const metaMap = createYMap();
|
|
606
605
|
metaMap.set( 'public_meta', 'new value' );
|
|
607
|
-
metaMap.set(
|
|
608
|
-
WORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE,
|
|
609
|
-
'exclude me'
|
|
610
|
-
);
|
|
606
|
+
metaMap.set( POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE, 'exclude me' );
|
|
611
607
|
map.set( 'meta', metaMap );
|
|
612
608
|
|
|
613
609
|
const editedRecord = {
|
|
@@ -626,8 +622,138 @@ describe( 'crdt', () => {
|
|
|
626
622
|
public_meta: 'new value', // from CRDT
|
|
627
623
|
} );
|
|
628
624
|
expect( changes.meta ).not.toHaveProperty(
|
|
629
|
-
|
|
625
|
+
POST_META_KEY_FOR_CRDT_DOC_PERSISTENCE
|
|
630
626
|
);
|
|
631
627
|
} );
|
|
628
|
+
|
|
629
|
+
describe( 'selection recalculation', () => {
|
|
630
|
+
it( 'includes recalculated selection when text is inserted before cursor', () => {
|
|
631
|
+
const ytext = addBlockToDoc( map, 'block-1', 'Hello world' );
|
|
632
|
+
|
|
633
|
+
// Record a selection at offset 5 (cursor between "Hello" and " world").
|
|
634
|
+
updateSelectionHistory( doc, {
|
|
635
|
+
selectionStart: {
|
|
636
|
+
clientId: 'block-1',
|
|
637
|
+
attributeKey: 'content',
|
|
638
|
+
offset: 5,
|
|
639
|
+
},
|
|
640
|
+
selectionEnd: {
|
|
641
|
+
clientId: 'block-1',
|
|
642
|
+
attributeKey: 'content',
|
|
643
|
+
offset: 5,
|
|
644
|
+
},
|
|
645
|
+
} );
|
|
646
|
+
|
|
647
|
+
// Simulate remote insertion: insert "XXX" at position 0.
|
|
648
|
+
ytext.insert( 0, 'XXX' );
|
|
649
|
+
|
|
650
|
+
const editedRecord = {
|
|
651
|
+
title: 'CRDT Title',
|
|
652
|
+
status: 'draft',
|
|
653
|
+
blocks: [],
|
|
654
|
+
} as unknown as Post;
|
|
655
|
+
|
|
656
|
+
const changes = getPostChangesFromCRDTDoc(
|
|
657
|
+
doc,
|
|
658
|
+
editedRecord,
|
|
659
|
+
mockPostType
|
|
660
|
+
);
|
|
661
|
+
|
|
662
|
+
expect( changes.selection ).toBeDefined();
|
|
663
|
+
expect( changes.selection?.selectionStart.offset ).toBe( 8 ); // 5 + 3
|
|
664
|
+
expect( changes.selection?.selectionStart.clientId ).toBe(
|
|
665
|
+
'block-1'
|
|
666
|
+
);
|
|
667
|
+
expect( changes.selection?.selectionStart.attributeKey ).toBe(
|
|
668
|
+
'content'
|
|
669
|
+
);
|
|
670
|
+
expect( changes.selection?.selectionEnd.offset ).toBe( 8 );
|
|
671
|
+
} );
|
|
672
|
+
|
|
673
|
+
it( 'includes recalculated selection when text is deleted before cursor', () => {
|
|
674
|
+
const ytext = addBlockToDoc( map, 'block-1', 'Hello world' );
|
|
675
|
+
|
|
676
|
+
// Record a selection at offset 8 (cursor between "Hello wo" and "rld").
|
|
677
|
+
updateSelectionHistory( doc, {
|
|
678
|
+
selectionStart: {
|
|
679
|
+
clientId: 'block-1',
|
|
680
|
+
attributeKey: 'content',
|
|
681
|
+
offset: 8,
|
|
682
|
+
},
|
|
683
|
+
selectionEnd: {
|
|
684
|
+
clientId: 'block-1',
|
|
685
|
+
attributeKey: 'content',
|
|
686
|
+
offset: 8,
|
|
687
|
+
},
|
|
688
|
+
} );
|
|
689
|
+
|
|
690
|
+
// Simulate remote deletion: delete "Hello" (5 chars at position 0).
|
|
691
|
+
ytext.delete( 0, 5 );
|
|
692
|
+
|
|
693
|
+
const editedRecord = {
|
|
694
|
+
title: 'CRDT Title',
|
|
695
|
+
status: 'draft',
|
|
696
|
+
blocks: [],
|
|
697
|
+
} as unknown as Post;
|
|
698
|
+
|
|
699
|
+
const changes = getPostChangesFromCRDTDoc(
|
|
700
|
+
doc,
|
|
701
|
+
editedRecord,
|
|
702
|
+
mockPostType
|
|
703
|
+
);
|
|
704
|
+
|
|
705
|
+
expect( changes.selection ).toBeDefined();
|
|
706
|
+
expect( changes.selection?.selectionStart.offset ).toBe( 3 ); // 8 - 5
|
|
707
|
+
} );
|
|
708
|
+
|
|
709
|
+
it( 'does not include selection when selection history is empty', () => {
|
|
710
|
+
addBlockToDoc( map, 'block-1', 'Hello world' );
|
|
711
|
+
|
|
712
|
+
const editedRecord = {
|
|
713
|
+
title: 'CRDT Title',
|
|
714
|
+
status: 'draft',
|
|
715
|
+
blocks: [],
|
|
716
|
+
} as unknown as Post;
|
|
717
|
+
|
|
718
|
+
const changes = getPostChangesFromCRDTDoc(
|
|
719
|
+
doc,
|
|
720
|
+
editedRecord,
|
|
721
|
+
mockPostType
|
|
722
|
+
);
|
|
723
|
+
|
|
724
|
+
expect( changes.selection ).toBeUndefined();
|
|
725
|
+
} );
|
|
726
|
+
} );
|
|
632
727
|
} );
|
|
633
728
|
} );
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* Helper to create a block with a Y.Text content attribute
|
|
732
|
+
* in the CRDT document.
|
|
733
|
+
*
|
|
734
|
+
* @param map
|
|
735
|
+
* @param clientId Block client ID.
|
|
736
|
+
* @param content Initial text content.
|
|
737
|
+
*/
|
|
738
|
+
function addBlockToDoc(
|
|
739
|
+
map: YMapWrap< YPostRecord >,
|
|
740
|
+
clientId: string,
|
|
741
|
+
content: string
|
|
742
|
+
): Y.Text {
|
|
743
|
+
let blocks = map.get( 'blocks' );
|
|
744
|
+
if ( ! ( blocks instanceof Y.Array ) ) {
|
|
745
|
+
blocks = new Y.Array< YBlock >();
|
|
746
|
+
map.set( 'blocks', blocks );
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
const block = createYMap< YBlockRecord >();
|
|
750
|
+
block.set( 'clientId', clientId );
|
|
751
|
+
const attrs = new Y.Map();
|
|
752
|
+
const ytext = new Y.Text( content );
|
|
753
|
+
attrs.set( 'content', ytext );
|
|
754
|
+
block.set( 'attributes', attrs );
|
|
755
|
+
block.set( 'innerBlocks', new Y.Array() );
|
|
756
|
+
( blocks as YBlocks ).push( [ block ] );
|
|
757
|
+
|
|
758
|
+
return ytext;
|
|
759
|
+
}
|