You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cudr_slate-collaborative/packages/client/src/withSocketIO.ts

123 lines
2.0 KiB

import io from 'socket.io-client'
import { AutomergeEditor } from './automerge-editor'
import { CollabAction } from '@slate-collaborative/bridge'
export interface SocketIOPluginOptions {
url: string
connectOpts: SocketIOClient.ConnectOpts
autoConnect?: boolean
onConnect?: () => void
onDisconnect?: () => void
}
export interface WithSocketIOEditor {
socket: SocketIOClient.Socket
connect: () => void
disconnect: () => void
send: (op: CollabAction) => void
receive: (op: CollabAction) => void
destroy: () => void
}
/**
* The `withSocketIO` plugin contains SocketIO layer logic.
*/
const withSocketIO = <T extends AutomergeEditor>(
editor: T,
options: SocketIOPluginOptions
) => {
const e = editor as T & WithSocketIOEditor
const { onConnect, onDisconnect, connectOpts, url, autoConnect } = options
/**
* Connect to Socket.
*/
e.connect = () => {
if (!e.socket) {
e.socket = io(url, { ...connectOpts })
e.socket.on('connect', () => {
e.clientId = e.socket.id
e.openConnection()
onConnect && onConnect()
})
}
e.socket.on('msg', (data: CollabAction) => {
e.receive(data)
})
e.socket.on('disconnect', () => {
e.gabageCursor()
onDisconnect && onDisconnect()
})
e.socket.connect()
return e
}
/**
* Disconnect from Socket.
*/
e.disconnect = () => {
e.socket.removeListener('msg')
e.socket.close()
e.closeConnection()
return e
}
/**
* Receive transport msg.
*/
e.receive = (msg: CollabAction) => {
switch (msg.type) {
case 'operation':
return e.receiveOperation(msg.payload)
case 'document':
return e.receiveDocument(msg.payload)
}
}
/**
* Send message to socket.
*/
e.send = (msg: CollabAction) => {
e.socket.emit('msg', msg)
}
/**
* Close socket and connection.
*/
e.destroy = () => {
e.socket.close()
e.closeConnection()
}
autoConnect && e.connect()
return e
}
export default withSocketIO