Skip to content

Conversation

@alecgeatches
Copy link
Contributor

As part of the work in add/flattened-rtc-blocks, we're making significant changes to the Y.Doc block data structure. This PR adds more complex and edge-case testing for mergeCrdtBlocks(), and also fixes a couple of bugs found during the process.

We will use these tests to reduce the risk that block data structure changes introduce merge errors.

Fixed bugs

  1. The handles block type changes from non-rich-text to rich-text test was failing when an attribute transitioned from a raw string to rich-text (Y.Text) content when the string value was the same. The fix is the attributeHasTypeChange boolean which ensure both the data type and content must be the same to skip a merge.

  2. Client Id deduplication was only running on a single level of blocks, which caused the removes duplicate clientIds across different nesting levels test. This meant a client ID could be freely duplicated as long as it was not in the same nesting level within the block structure. The code has been changed to:

    1. Merge blocks, then
    2. Check at the top level that all client IDs are unique.

    This required making an internal mergeCrdtBlocksInternal() function that does the normal work of what mergeCrdtBlocks() did previously, then run the top level logic after. This ensures the whole block structure of client IDs are deduplicated and avoids recursively making that check.

Testing Instructions

To run the CRDT test suite:

npm run test:unit -- --testPathPattern=crdt-blocks

@alecgeatches alecgeatches marked this pull request as ready for review December 31, 2025 20:26
@alecgeatches alecgeatches requested a review from nerrad as a code owner December 31, 2025 20:26
@github-actions github-actions bot added the [Package] Core data /packages/core-data label Dec 31, 2025
@github-actions
Copy link

Warning: Type of PR label mismatch

To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.

  • Required label: Any label starting with [Type].
  • Labels found: [Package] Core data.

Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task.

@github-actions
Copy link

github-actions bot commented Dec 31, 2025

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: alecgeatches <[email protected]>
Co-authored-by: chriszarate <[email protected]>
Co-authored-by: SirLouen <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@alecgeatches
Copy link
Contributor Author

@chriszarate Added a few new tests for mergeCrdtBlocks() and a couple of bug fixes. Please take a look when you have a chance.

@alecgeatches alecgeatches changed the title Add more robust mergeCrdtBlocks() testing, fix edge cases Real-time collaboration: Add more robust mergeCrdtBlocks() testing Dec 31, 2025
Comment on lines -386 to +425
if ( ! clientId ) {
continue;
if ( clientId ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this logic inverted for any particular reason?

Copy link
Contributor Author

@alecgeatches alecgeatches Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just allows the recursion on innerBlocks to run even if the current block is missing a client ID. I'm not clear on when a clientId will be missing from a block or if that's even a real possibility, but it was accounted for in the original code. Do you have any insight on when this happens? Should we also bail on innerBlocks in this unusual case?

Copy link
Member

@SirLouen SirLouen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alecgeatches this patch is not applying for me. It's rebased to the lastest trunk?

I cannot find a cursorPosition in crdt-blocks-ts

https://github.com/WordPress/gutenberg/blob/trunk/packages/core-data/src/utils/crdt-blocks.ts

@alecgeatches
Copy link
Contributor Author

@SirLouen This PR is currently into our WordPress:wpvip/rtc-plugin branch, which we use to make changes upstream of actual Gutenberg trunk.

You can see cursorPosition in the branch: https://github.com/WordPress/gutenberg/blob/wpvip/rtc-plugin/packages/core-data/src/utils/crdt-blocks.ts#L195

@SirLouen
Copy link
Member

@alecgeatches is this an unofficial fork or something? Isn't planned to be merged into trunk?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Core data /packages/core-data

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants