-
Notifications
You must be signed in to change notification settings - Fork 806
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
feat(yjs): add WebRTC provider support alongside Hocuspocus #4142
base: main
Are you sure you want to change the base?
Conversation
Implements unified provider interface to support both p2p and server-based collaboration
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
🦋 Changeset detectedLatest commit: 08c9851 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Thanks for the PR, it's a great one! Feel free to add a demo example so we get more yjs adoption and feedback. We would host the signaling server. |
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.
Could you just write down a short migration snippet?
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.
It looks like no migration is necessary, since the providerType
defaults to hocuspocus
and hocuspocusProviderOptions
hasn't been changed.
This should probably be a minor changeset rather than major.
if (providerType === 'webrtc') { | ||
const webrtcProvider = new YWebrtcProvider( | ||
webrtcProviderOptions!.roomName, | ||
new Y.Doc(), | ||
{ | ||
filterBcConns: webrtcProviderOptions!.filterBcConns, | ||
maxConns: webrtcProviderOptions!.maxConns, | ||
password: webrtcProviderOptions!.password, | ||
peerOpts: webrtcProviderOptions!.peerOpts, | ||
signaling: webrtcProviderOptions!.signaling, | ||
} | ||
); | ||
|
||
provider = new WebRTCProviderWrapper(webrtcProvider); | ||
|
||
// Set connection status | ||
webrtcProvider.on('status', (status) => { | ||
if (status.connected) { | ||
setOption('isConnected', true); | ||
setOption('isSynced', true); | ||
} else { | ||
setOption('isConnected', false); | ||
setOption('isSynced', false); | ||
} | ||
}); | ||
|
||
webrtcProvider.on('synced', (synced) => { | ||
setOption('isSynced', synced.synced); | ||
}); | ||
} else { | ||
const hocusProvider = new HocuspocusProvider({ | ||
...hocuspocusProviderOptions!, | ||
onAwarenessChange() {}, | ||
onConnect() { | ||
setOption('isConnected', true); | ||
hocuspocusProviderOptions!.onConnect?.(); | ||
}, | ||
onDisconnect(data) { | ||
setOption('isConnected', false); | ||
setOption('isSynced', false); | ||
hocuspocusProviderOptions!.onDisconnect?.(data); | ||
}, | ||
onSynced(data) { | ||
setOption('isSynced', true); | ||
hocuspocusProviderOptions!.onSynced?.(data); | ||
}, | ||
}); | ||
|
||
provider = new HocuspocusProviderWrapper(hocusProvider); |
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.
This logic might be neater if the creation of the provider object and the event handlers were refactored into the wrapper classes, so that the extend
code doesn't need so much conditional logic.
const handlers: ProviderEventHandlers = {
onConnect: () => setOption('isConnected', true),
onDisconnect: () => {
setOption('isConnected', false);
setOption('isSynced', false);
},
onSynced: () => setOption('isSynced', true),
};
const provider = providerType === 'webrtc'
? new YWebrtcProvider({
options: webrtcProviderOptions!,
handlers,
})
: new HocuspocusProvider({
options: hocuspocusProviderOptions!,
handlers,
});
## April 2025 #21 | ||
|
||
### April 1 #21.1 | ||
|
||
Plate 47 - WebRTC collaboration | ||
|
||
- `plate-yjs`: Major update with WebRTC provider support | ||
- Added WebRTC provider support for peer-to-peer collaboration | ||
- Created unified provider interface for consistent API | ||
- Maintained backward compatibility with Hocuspocus | ||
- Added configuration options for both providers | ||
|
||
```tsx | ||
// WebRTC provider configuration | ||
YjsPlugin.configure({ | ||
options: { | ||
providerType: 'webrtc', | ||
webrtcOptions: { | ||
// WebRTC specific options | ||
signaling: ['wss://your-signaling-server'], | ||
password: 'optional-room-password', | ||
}, | ||
}, | ||
}); | ||
|
||
// Hocuspocus provider (existing approach) | ||
YjsPlugin.configure({ | ||
options: { | ||
providerType: 'hocuspocus', // or undefined for backward compatibility | ||
hocuspocusOptions: { | ||
// Hocuspocus specific options | ||
url: 'wss://your-hocuspocus-server', | ||
}, | ||
}, | ||
}); | ||
``` |
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.
The components/changelog.mdx
file is only used for changes to Plate's UI components (which require a separate changelog since they aren't published as an NPM package). If you could move this sample code into the .changeset/three-humans-attack.md
file, that would be great.
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.
No problem I will do that.
Implements unified provider interface to support both p2p and server-based collaboration
Changes
Usage
Users can now choose between server-based (Hocuspocus) or peer-to-peer (WebRTC) collaboration by configuring the provider type in the YjsPlugin options.
Testing