Skip to content

RTC: Fix stale CRDT document persisted on save#75975

Merged
chriszarate merged 4 commits intotrunkfrom
fix/sync-stale-crdt-doc-on-save
Mar 2, 2026
Merged

RTC: Fix stale CRDT document persisted on save#75975
chriszarate merged 4 commits intotrunkfrom
fix/sync-stale-crdt-doc-on-save

Conversation

@shekharnwagh
Copy link
Copy Markdown
Contributor

What?

Fix stale CRDT document being persisted during save when real-time collaboration is enabled.

Why?

When sync is enabled, Y.Doc updates are deferred via setTimeout(0) for performance. saveEntityRecord calls __unstablePrePersist to serialize the CRDT document, but it was doing so without yielding to the event loop first. This meant the serialized _crdt_document was stale — it didn't include the most recent Y.Doc updates. On reload, _applyPersistedCrdtDoc detected the mismatch and triggered an unnecessary reconciliation save.

How?

  • Add a setTimeout(0) yield inside saveEntityRecord before calling __unstablePrePersist, only when syncConfig is present. This flushes any pending deferred Y.Doc updates before serialization.
  • Extract repeated waitForFunction/evaluate blocks from the collaboration persistence E2E tests into three reusable CollaborationUtils helpers: waitForEntityReady, waitForEntityReadyAndSaveSettled, and getCrdtDocument.
  • Add a new E2E test (persisted CRDT document matches content after save and reload) that verifies the CRDT document is identical before and after a save-reload cycle.

Testing Instructions

  1. Enable real-time collaboration in Settings → Writing.
  2. Create a new draft post with a paragraph block.
  3. Type some content.
  4. Open the browser Network tab and filter by posts/:id to see REST API calls to wp/v2/posts/:id.

On trunk (before this PR):

  1. Click Publish — observe a POST request to posts/:id.
  2. Reload the page.
  3. A second POST request to posts/:id fires automatically after reload — this is the unnecessary reconciliation save caused by the stale CRDT document.

On this branch (after this PR):

  1. Click Publish — observe a POST request to posts/:id.
  2. Reload the page.
  3. No additional POST request to posts/:id fires — the persisted CRDT document is up-to-date so no reconciliation save is triggered.

Automated

npx playwright test --config test/e2e/playwright.config.ts test/e2e/specs/editor/collaboration/collaboration-persistence.spec.ts

All 3 tests should pass. The third test (persisted CRDT document matches content after save and reload) fails without the actions.js fix.

Testing Instructions for Keyboard

N/A — no UI changes.

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

Labels

Backported to WP Core Pull request that has been successfully merged into WP Core [Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration [Package] Core data /packages/core-data [Package] Sync [Type] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants