compatible with yjs@v13-79

This commit is contained in:
Kevin Jahns
2019-04-24 08:07:37 +02:00
parent 9208e699e2
commit 01519447ca
6 changed files with 14846 additions and 69 deletions

View File

@@ -54,6 +54,10 @@ const readMessage = (doc, buf) => {
return encoder
}
/**
* @param {WebsocketsSharedDocument} doc
* @param {string} url
*/
const setupWS = (doc, url) => {
const websocket = new WebSocket(url)
websocket.binaryType = 'arraybuffer'
@@ -68,9 +72,12 @@ const setupWS = (doc, url) => {
doc.ws = null
doc.wsconnected = false
// update awareness (all users left)
/**
* @type {Array<number>}
*/
const removed = []
doc.getAwarenessInfo().forEach((_, userid) => {
removed.push(userid)
doc.getAwarenessInfo().forEach((_, clientID) => {
removed.push(clientID)
})
doc.awareness = new Map()
doc.emit('awareness', [{
@@ -89,40 +96,61 @@ const setupWS = (doc, url) => {
// always send sync step 1 when connected
const encoder = encoding.createEncoder()
encoding.writeVarUint(encoder, messageSync)
syncProtocol.writeSyncStep1(encoder, doc)
syncProtocol.writeSyncStep1(encoder, doc.store)
websocket.send(encoding.toBuffer(encoder))
// force send stored awareness info
doc.setAwarenessField(null, null)
}
}
const broadcastUpdate = (y, transaction) => {
if (transaction.encodedStructsLen > 0) {
/**
* @param {Y.Transaction} transaction
* @param {WebsocketsSharedDocument} y
*/
const broadcastUpdate = (transaction, y) => {
if (transaction.updateMessage !== null) {
y.mux(() => {
const encoder = encoding.createEncoder()
encoding.writeVarUint(encoder, messageSync)
syncProtocol.writeUpdate(encoder, transaction.encodedStructsLen, transaction.encodedStructs)
const buf = encoding.toBuffer(encoder)
if (y.wsconnected) {
y.ws.send(buf)
const updateMessage = transaction.updateMessage
if (updateMessage !== null) {
const encoder = encoding.createEncoder()
encoding.writeVarUint(encoder, messageSync)
syncProtocol.writeUpdate(encoder, updateMessage)
const buf = encoding.toBuffer(encoder)
if (y.wsconnected) {
// @ts-ignore We know that wsconnected = true
y.ws.send(buf)
}
bc.publish(y.url, buf)
}
bc.publish(y.url, buf)
})
}
}
class WebsocketsSharedDocument extends Y.Y {
/**
* @param {string} url
* @param {Object} opts
*/
constructor (url, opts) {
super(opts)
this.url = url
this.wsconnected = false
this.mux = mutex.createMutex()
this.ws = null
/**
* @type {Object<string,Object>}
*/
this._localAwarenessState = {}
this.awareness = new Map()
this.awarenessClock = new Map()
this.url = url
this.wsconnected = false
this.mux = mutex.createMutex()
/**
* @type {WebSocket?}
*/
this.ws = null
setupWS(this, url)
this.on('afterTransaction', broadcastUpdate)
/**
* @param {ArrayBuffer} data
*/
this._bcSubscriber = data => {
const encoder = readMessage(this, data) // already muxed
this.mux(() => {
@@ -136,7 +164,7 @@ class WebsocketsSharedDocument extends Y.Y {
this.mux(() => {
const encoder = encoding.createEncoder()
encoding.writeVarUint(encoder, messageSync)
syncProtocol.writeSyncStep1(encoder, this)
syncProtocol.writeSyncStep1(encoder, this.store)
bc.publish(url, encoding.toBuffer(encoder))
})
}
@@ -146,17 +174,22 @@ class WebsocketsSharedDocument extends Y.Y {
getAwarenessInfo () {
return this.awareness
}
/**
* @param {string?} field
* @param {Object} value
*/
setAwarenessField (field, value) {
if (field !== null) {
this._localAwarenessState[field] = value
}
if (this.wsconnected) {
const clock = (this.awarenessClock.get(this.userID) || 0) + 1
this.awarenessClock.set(this.userID, clock)
const clock = (this.awarenessClock.get(this.clientID) || 0) + 1
this.awarenessClock.set(this.clientID, clock)
const encoder = encoding.createEncoder()
encoding.writeVarUint(encoder, messageAwareness)
awarenessProtocol.writeUsersStateChange(encoder, [{ userID: this.userID, state: this._localAwarenessState, clock }])
awarenessProtocol.writeUsersStateChange(encoder, [{ clientID: this.clientID, state: this._localAwarenessState, clock }])
const buf = encoding.toBuffer(encoder)
// @ts-ignore we know that wsconnected = true
this.ws.send(buf)
}
}
@@ -173,6 +206,9 @@ class WebsocketsSharedDocument extends Y.Y {
* const ydocument = provider.get('my-document-name')
*/
export class WebsocketProvider {
/**
* @param {string} url
*/
constructor (url) {
// ensure that url is always ends with /
while (url[url.length - 1] === '/') {
@@ -186,6 +222,7 @@ export class WebsocketProvider {
}
/**
* @param {string} name
* @param {Object} [opts]
* @return {WebsocketsSharedDocument}
*/
get (name, opts) {