diff --git a/src/y-websocket.js b/src/y-websocket.js index 5911fdd..c96bdc6 100644 --- a/src/y-websocket.js +++ b/src/y-websocket.js @@ -1,7 +1,3 @@ -/* -Unlike stated in the LICENSE file, it is not necessary to include the copyright notice and permission notice when you copy code from this file. -*/ - /** * @module provider/websocket */ @@ -31,25 +27,71 @@ export const messageAuth = 2 */ const messageHandlers = [] -messageHandlers[messageSync] = (encoder, decoder, provider, emitSynced, messageType) => { +messageHandlers[messageSync] = ( + encoder, + decoder, + provider, + emitSynced, + _messageType +) => { encoding.writeVarUint(encoder, messageSync) - const syncMessageType = syncProtocol.readSyncMessage(decoder, encoder, provider.doc, provider) - if (emitSynced && syncMessageType === syncProtocol.messageYjsSyncStep2 && !provider.synced) { + const syncMessageType = syncProtocol.readSyncMessage( + decoder, + encoder, + provider.doc, + provider + ) + if ( + emitSynced && syncMessageType === syncProtocol.messageYjsSyncStep2 && + !provider.synced + ) { provider.synced = true } } -messageHandlers[messageQueryAwareness] = (encoder, decoder, provider, emitSynced, messageType) => { +messageHandlers[messageQueryAwareness] = ( + encoder, + _decoder, + provider, + _emitSynced, + _messageType +) => { encoding.writeVarUint(encoder, messageAwareness) - encoding.writeVarUint8Array(encoder, awarenessProtocol.encodeAwarenessUpdate(provider.awareness, Array.from(provider.awareness.getStates().keys()))) + encoding.writeVarUint8Array( + encoder, + awarenessProtocol.encodeAwarenessUpdate( + provider.awareness, + Array.from(provider.awareness.getStates().keys()) + ) + ) } -messageHandlers[messageAwareness] = (encoder, decoder, provider, emitSynced, messageType) => { - awarenessProtocol.applyAwarenessUpdate(provider.awareness, decoding.readVarUint8Array(decoder), provider) +messageHandlers[messageAwareness] = ( + _encoder, + decoder, + provider, + _emitSynced, + _messageType +) => { + awarenessProtocol.applyAwarenessUpdate( + provider.awareness, + decoding.readVarUint8Array(decoder), + provider + ) } -messageHandlers[messageAuth] = (encoder, decoder, provider, emitSynced, messageType) => { - authProtocol.readAuthMessage(decoder, provider.doc, (_ydoc, reason) => permissionDeniedHandler(provider, reason)) +messageHandlers[messageAuth] = ( + _encoder, + decoder, + provider, + _emitSynced, + _messageType +) => { + authProtocol.readAuthMessage( + decoder, + provider.doc, + (_ydoc, reason) => permissionDeniedHandler(provider, reason) + ) } // @todo - this should depend on awareness.outdatedTime @@ -59,7 +101,8 @@ const messageReconnectTimeout = 30000 * @param {WebsocketProvider} provider * @param {string} reason */ -const permissionDeniedHandler = (provider, reason) => console.warn(`Permission denied to access ${provider.url}.\n${reason}`) +const permissionDeniedHandler = (provider, reason) => + console.warn(`Permission denied to access ${provider.url}.\n${reason}`) /** * @param {WebsocketProvider} provider @@ -83,7 +126,7 @@ const readMessage = (provider, buf, emitSynced) => { /** * @param {WebsocketProvider} provider */ -const setupWS = provider => { +const setupWS = (provider) => { if (provider.shouldConnect && provider.ws === null) { const websocket = new provider._WS(provider.url) websocket.binaryType = 'arraybuffer' @@ -92,17 +135,17 @@ const setupWS = provider => { provider.wsconnected = false provider.synced = false - websocket.onmessage = event => { + websocket.onmessage = (event) => { provider.wsLastMessageReceived = time.getUnixTime() const encoder = readMessage(provider, new Uint8Array(event.data), true) if (encoding.length(encoder) > 1) { websocket.send(encoding.toUint8Array(encoder)) } } - websocket.onerror = event => { + websocket.onerror = (event) => { provider.emit('connection-error', [event, provider]) } - websocket.onclose = event => { + websocket.onclose = (event) => { provider.emit('connection-close', [event, provider]) provider.ws = null provider.wsconnecting = false @@ -110,7 +153,13 @@ const setupWS = provider => { provider.wsconnected = false provider.synced = false // update awareness (all users except local left) - awarenessProtocol.removeAwarenessStates(provider.awareness, Array.from(provider.awareness.getStates().keys()).filter(client => client !== provider.doc.clientID), provider) + awarenessProtocol.removeAwarenessStates( + provider.awareness, + Array.from(provider.awareness.getStates().keys()).filter((client) => + client !== provider.doc.clientID + ), + provider + ) provider.emit('status', [{ status: 'disconnected' }]) @@ -119,7 +168,14 @@ const setupWS = provider => { } // Start with no reconnect timeout and increase timeout by // using exponential backoff starting with 100ms - setTimeout(setupWS, math.min(math.pow(2, provider.wsUnsuccessfulReconnects) * 100, provider.maxBackoffTime), provider) + setTimeout( + setupWS, + math.min( + math.pow(2, provider.wsUnsuccessfulReconnects) * 100, + provider.maxBackoffTime + ), + provider + ) } websocket.onopen = () => { provider.wsLastMessageReceived = time.getUnixTime() @@ -138,7 +194,12 @@ const setupWS = provider => { if (provider.awareness.getLocalState() !== null) { const encoderAwarenessState = encoding.createEncoder() encoding.writeVarUint(encoderAwarenessState, messageAwareness) - encoding.writeVarUint8Array(encoderAwarenessState, awarenessProtocol.encodeAwarenessUpdate(provider.awareness, [provider.doc.clientID])) + encoding.writeVarUint8Array( + encoderAwarenessState, + awarenessProtocol.encodeAwarenessUpdate(provider.awareness, [ + provider.doc.clientID + ]) + ) websocket.send(encoding.toUint8Array(encoderAwarenessState)) } } @@ -206,7 +267,8 @@ export class WebsocketProvider extends Observable { const encodedParams = url.encodeQueryParams(params) this.maxBackoffTime = maxBackoffTime this.bcChannel = serverUrl + '/' + roomname - this.url = serverUrl + '/' + roomname + (encodedParams.length === 0 ? '' : '?' + encodedParams) + this.url = serverUrl + '/' + roomname + + (encodedParams.length === 0 ? '' : '?' + encodedParams) this.roomname = roomname this.doc = doc this._WS = WebSocketPolyfill @@ -276,17 +338,24 @@ export class WebsocketProvider extends Observable { this.doc.on('update', this._updateHandler) /** * @param {any} changed - * @param {any} origin + * @param {any} _origin */ - this._awarenessUpdateHandler = ({ added, updated, removed }, origin) => { + this._awarenessUpdateHandler = ({ added, updated, removed }, _origin) => { const changedClients = added.concat(updated).concat(removed) const encoder = encoding.createEncoder() encoding.writeVarUint(encoder, messageAwareness) - encoding.writeVarUint8Array(encoder, awarenessProtocol.encodeAwarenessUpdate(awareness, changedClients)) + encoding.writeVarUint8Array( + encoder, + awarenessProtocol.encodeAwarenessUpdate(awareness, changedClients) + ) broadcastMessage(this, encoding.toUint8Array(encoder)) } this._beforeUnloadHandler = () => { - awarenessProtocol.removeAwarenessStates(this.awareness, [doc.clientID], 'window unload') + awarenessProtocol.removeAwarenessStates( + this.awareness, + [doc.clientID], + 'window unload' + ) } if (typeof window !== 'undefined') { window.addEventListener('beforeunload', this._beforeUnloadHandler) @@ -295,7 +364,11 @@ export class WebsocketProvider extends Observable { } awareness.on('update', this._awarenessUpdateHandler) this._checkInterval = /** @type {any} */ (setInterval(() => { - if (this.wsconnected && messageReconnectTimeout < time.getUnixTime() - this.wsLastMessageReceived) { + if ( + this.wsconnected && + messageReconnectTimeout < + time.getUnixTime() - this.wsLastMessageReceived + ) { // no message received in a long time - not even your own awareness // updates (which are updated every 15 seconds) /** @type {WebSocket} */ (this.ws).close() @@ -359,19 +432,37 @@ export class WebsocketProvider extends Observable { // write queryAwareness const encoderAwarenessQuery = encoding.createEncoder() encoding.writeVarUint(encoderAwarenessQuery, messageQueryAwareness) - bc.publish(this.bcChannel, encoding.toUint8Array(encoderAwarenessQuery), this) + bc.publish( + this.bcChannel, + encoding.toUint8Array(encoderAwarenessQuery), + this + ) // broadcast local awareness state const encoderAwarenessState = encoding.createEncoder() encoding.writeVarUint(encoderAwarenessState, messageAwareness) - encoding.writeVarUint8Array(encoderAwarenessState, awarenessProtocol.encodeAwarenessUpdate(this.awareness, [this.doc.clientID])) - bc.publish(this.bcChannel, encoding.toUint8Array(encoderAwarenessState), this) + encoding.writeVarUint8Array( + encoderAwarenessState, + awarenessProtocol.encodeAwarenessUpdate(this.awareness, [ + this.doc.clientID + ]) + ) + bc.publish( + this.bcChannel, + encoding.toUint8Array(encoderAwarenessState), + this + ) } disconnectBc () { // broadcast message with local awareness state set to null (indicating disconnect) const encoder = encoding.createEncoder() encoding.writeVarUint(encoder, messageAwareness) - encoding.writeVarUint8Array(encoder, awarenessProtocol.encodeAwarenessUpdate(this.awareness, [this.doc.clientID], new Map())) + encoding.writeVarUint8Array( + encoder, + awarenessProtocol.encodeAwarenessUpdate(this.awareness, [ + this.doc.clientID + ], new Map()) + ) broadcastMessage(this, encoding.toUint8Array(encoder)) if (this.bcconnected) { bc.unsubscribe(this.bcChannel, this._bcSubscriber)