45 lines
1.1 KiB
TypeScript
45 lines
1.1 KiB
TypeScript
/**
|
|
* Y.js collaboration provider for rNotes
|
|
*
|
|
* Wraps y-websocket's WebsocketProvider to connect to the y-websocket
|
|
* sidecar server for real-time collaborative editing.
|
|
*/
|
|
|
|
import * as Y from 'yjs'
|
|
import { WebsocketProvider } from 'y-websocket'
|
|
|
|
const COLLAB_WS_URL = process.env.NEXT_PUBLIC_COLLAB_WS_URL || 'ws://localhost:1234'
|
|
|
|
export interface CollabState {
|
|
connected: boolean
|
|
synced: boolean
|
|
peerCount: number
|
|
}
|
|
|
|
export function createCollabProvider(
|
|
noteId: string,
|
|
ydoc: Y.Doc,
|
|
user: { name: string; color: string },
|
|
onStateChange?: (state: CollabState) => void,
|
|
): WebsocketProvider {
|
|
const roomName = `note-${noteId}`
|
|
const provider = new WebsocketProvider(COLLAB_WS_URL, roomName, ydoc)
|
|
|
|
// Set local awareness (cursor name/color)
|
|
provider.awareness.setLocalStateField('user', user)
|
|
|
|
const emitState = () => {
|
|
onStateChange?.({
|
|
connected: provider.wsconnected,
|
|
synced: provider.synced,
|
|
peerCount: provider.awareness.getStates().size - 1,
|
|
})
|
|
}
|
|
|
|
provider.on('status', emitState)
|
|
provider.on('sync', emitState)
|
|
provider.awareness.on('update', emitState)
|
|
|
|
return provider
|
|
}
|