-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document the current state of the Real-Time collaboration experiment #54932
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Status of the sync experiment in Gutenberg | ||
|
||
The sync package is part of an ongoing research effort to lay the groundwork of Real-Time Collaboration in Gutenberg. | ||
|
||
Relevant docs: | ||
|
||
- https://make.wordpress.org/core/2023/07/13/real-time-collaboration-architecture/ | ||
- https://github.com/WordPress/gutenberg/issues/52593 | ||
- https://docs.yjs.dev/ | ||
|
||
## Enable the experiment | ||
|
||
The experiment can be enabled in the "Guteberg > Experiments" page. When it is enabled (search for `gutenberg-sync-collaboration` in the codebase), the client receives two new pieces of data: | ||
|
||
- `window.__experimentalEnableSync`: boolean. Used by the `core-data` package to determine whether to bootstrap and use the sync provider offered by the `sync` package. | ||
- `window.__experimentalCollaborativeEditingSecret`: string. A secret used by the `sync` package to create a secure connection among peers. | ||
|
||
## The data flow | ||
|
||
The current experiment updates `core-data` to leverage the YJS library for synchronization and merging changes. Each core-data entity record represents a YJS document and updates to the `--edit` record are broadcasted among peers. | ||
|
||
These are the specific checkpoints: | ||
|
||
1. REGISTER. | ||
- See `getSyncProvider().register( ... )` in `registerSyncConfigs`. | ||
- Not all entity types are sync-enabled at the moment, look at those that declare a `syncConfig` and `syncObjectType` in `rootEntitiesConfig`. | ||
2. BOOTSTRAP. | ||
- See `getSyncProvider().bootstrap( ... )` in `getEntityRecord`. | ||
- The `bootstrap` function fetches the entity and sets up the callback that will dispatch the relevant Redux action when document changes are broadcasted from other peers. | ||
3. UPDATE. | ||
- See `getSyncProvider().update( ... )` in `editEntityRecord`. | ||
- Each change done by a peer to the `--edit` entity record (local changes, not persisted ones) is broadcasted to the others. | ||
- The data that is shared is the whole block list. | ||
|
||
This is the data flow when the peer A makes a local change: | ||
|
||
- Peer A makes a local change. | ||
- Peer A triggers a `getSyncProvider().update( ... )` request (see `editEntityRecord`). | ||
- All peers (including A) receive the broadcasted change and execute the callback (see `updateHandler` in `createSyncProvider.bootstrap`). | ||
- All peers (including A) trigger a `EDIT_ENTITY_RECORD` redux action. | ||
|
||
## What works and what doesn't | ||
|
||
- Undo/redo does not work. | ||
- Changes can be persisted and the publish/update button should react accordingly for all peers. | ||
- Offline. | ||
- Changes are stored in the browser's local storage (indexedDB) for each user/peer. Users can navigate away from the document and they'll see the changes when they come back. | ||
- Visually, there is no hint that they are seeing local/offline changes vs published ones. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand this point. It seems independent of real time collaboration or offline editing. When you have edits, you just see that your post is unsaved no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed that point. I'm not sure if it's related to offline mode, it sounds like an issue with the button status, see #54932 (comment) |
||
- Offline changes can be deleted via visiting the browser's database in all peers, then reload the document. | ||
- Documents can get out of sync. For example: | ||
- Two peers open the same document. | ||
- One of them (A) leaves the document. Then, the remaining user (B) makes changes. | ||
- When A comes back to the document, the changes B made are not visible to A. | ||
- Entities | ||
- Not all entities are synced. For example, global styles are not. Look at the `base` entity config for an example (it declares `syncConfig` and `syncObjectType` properties). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think this could be in the README directly, why did you go with
CODE.md
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure where to put this, given it documents an experiment that is split across
core-data
andsync
packages. The README is published in the block editor handbook, and I'm not sure if it merits such visibility. I thought the README was also used in the page of the public@wordpress/sync
package, although it seems it doesn't.Happy to add it to the
README
or move it anywhere else.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's fine to keep it separate like that but link to it from the README or something for discoverability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we iterate on this file until we have something we are happy with, and then we decide where to show it?