UNPKG

y-websocket

Version:
1 lines 29.9 kB
{"version":3,"file":"y-websocket.cjs","sources":["../src/y-websocket.js"],"sourcesContent":["/**\n * @module provider/websocket\n */\n\n/* eslint-env browser */\n\nimport * as Y from 'yjs' // eslint-disable-line\nimport * as bc from 'lib0/broadcastchannel'\nimport * as time from 'lib0/time'\nimport * as encoding from 'lib0/encoding'\nimport * as decoding from 'lib0/decoding'\nimport * as syncProtocol from 'y-protocols/sync'\nimport * as authProtocol from 'y-protocols/auth'\nimport * as awarenessProtocol from 'y-protocols/awareness'\nimport { ObservableV2 } from 'lib0/observable'\nimport * as math from 'lib0/math'\nimport * as url from 'lib0/url'\nimport * as env from 'lib0/environment'\n\nexport const messageSync = 0\nexport const messageQueryAwareness = 3\nexport const messageAwareness = 1\nexport const messageAuth = 2\n\n/**\n * encoder, decoder, provider, emitSynced, messageType\n * @type {Array<function(encoding.Encoder, decoding.Decoder, WebsocketProvider, boolean, number):void>}\n */\nconst messageHandlers = []\n\nmessageHandlers[messageSync] = (\n encoder,\n decoder,\n provider,\n emitSynced,\n _messageType\n) => {\n encoding.writeVarUint(encoder, messageSync)\n const syncMessageType = syncProtocol.readSyncMessage(\n decoder,\n encoder,\n provider.doc,\n provider\n )\n if (\n emitSynced && syncMessageType === syncProtocol.messageYjsSyncStep2 &&\n !provider.synced\n ) {\n provider.synced = true\n }\n}\n\nmessageHandlers[messageQueryAwareness] = (\n encoder,\n _decoder,\n provider,\n _emitSynced,\n _messageType\n) => {\n encoding.writeVarUint(encoder, messageAwareness)\n encoding.writeVarUint8Array(\n encoder,\n awarenessProtocol.encodeAwarenessUpdate(\n provider.awareness,\n Array.from(provider.awareness.getStates().keys())\n )\n )\n}\n\nmessageHandlers[messageAwareness] = (\n _encoder,\n decoder,\n provider,\n _emitSynced,\n _messageType\n) => {\n awarenessProtocol.applyAwarenessUpdate(\n provider.awareness,\n decoding.readVarUint8Array(decoder),\n provider\n )\n}\n\nmessageHandlers[messageAuth] = (\n _encoder,\n decoder,\n provider,\n _emitSynced,\n _messageType\n) => {\n authProtocol.readAuthMessage(\n decoder,\n provider.doc,\n (_ydoc, reason) => permissionDeniedHandler(provider, reason)\n )\n}\n\n// @todo - this should depend on awareness.outdatedTime\nconst messageReconnectTimeout = 30000\n\n/**\n * @param {WebsocketProvider} provider\n * @param {string} reason\n */\nconst permissionDeniedHandler = (provider, reason) =>\n console.warn(`Permission denied to access ${provider.url}.\\n${reason}`)\n\n/**\n * @param {WebsocketProvider} provider\n * @param {Uint8Array} buf\n * @param {boolean} emitSynced\n * @return {encoding.Encoder}\n */\nconst readMessage = (provider, buf, emitSynced) => {\n const decoder = decoding.createDecoder(buf)\n const encoder = encoding.createEncoder()\n const messageType = decoding.readVarUint(decoder)\n const messageHandler = provider.messageHandlers[messageType]\n if (/** @type {any} */ (messageHandler)) {\n messageHandler(encoder, decoder, provider, emitSynced, messageType)\n } else {\n console.error('Unable to compute message')\n }\n return encoder\n}\n\n/**\n * Outsource this function so that a new websocket connection is created immediately.\n * I suspect that the `ws.onclose` event is not always fired if there are network issues.\n *\n * @param {WebsocketProvider} provider\n * @param {WebSocket} ws\n * @param {CloseEvent | null} event\n */\nconst closeWebsocketConnection = (provider, ws, event) => {\n if (ws === provider.ws) {\n provider.emit('connection-close', [event, provider])\n provider.ws = null\n ws.close()\n provider.wsconnecting = false\n if (provider.wsconnected) {\n provider.wsconnected = false\n provider.synced = false\n // update awareness (all users except local left)\n awarenessProtocol.removeAwarenessStates(\n provider.awareness,\n Array.from(provider.awareness.getStates().keys()).filter((client) =>\n client !== provider.doc.clientID\n ),\n provider\n )\n provider.emit('status', [{\n status: 'disconnected'\n }])\n } else {\n provider.wsUnsuccessfulReconnects++\n }\n // Start with no reconnect timeout and increase timeout by\n // using exponential backoff starting with 100ms\n setTimeout(\n setupWS,\n math.min(\n math.pow(2, provider.wsUnsuccessfulReconnects) * 100,\n provider.maxBackoffTime\n ),\n provider\n )\n }\n}\n\n/**\n * @param {WebsocketProvider} provider\n */\nconst setupWS = (provider) => {\n if (provider.shouldConnect && provider.ws === null) {\n const websocket = new provider._WS(provider.url, provider.protocols)\n websocket.binaryType = 'arraybuffer'\n provider.ws = websocket\n provider.wsconnecting = true\n provider.wsconnected = false\n provider.synced = false\n\n websocket.onmessage = (event) => {\n provider.wsLastMessageReceived = time.getUnixTime()\n const encoder = readMessage(provider, new Uint8Array(event.data), true)\n if (encoding.length(encoder) > 1) {\n websocket.send(encoding.toUint8Array(encoder))\n }\n }\n websocket.onerror = (event) => {\n provider.emit('connection-error', [event, provider])\n }\n websocket.onclose = (event) => {\n closeWebsocketConnection(provider, websocket, event)\n }\n websocket.onopen = () => {\n provider.wsLastMessageReceived = time.getUnixTime()\n provider.wsconnecting = false\n provider.wsconnected = true\n provider.wsUnsuccessfulReconnects = 0\n provider.emit('status', [{\n status: 'connected'\n }])\n // always send sync step 1 when connected\n const encoder = encoding.createEncoder()\n encoding.writeVarUint(encoder, messageSync)\n syncProtocol.writeSyncStep1(encoder, provider.doc)\n websocket.send(encoding.toUint8Array(encoder))\n // broadcast local awareness state\n if (provider.awareness.getLocalState() !== null) {\n const encoderAwarenessState = encoding.createEncoder()\n encoding.writeVarUint(encoderAwarenessState, messageAwareness)\n encoding.writeVarUint8Array(\n encoderAwarenessState,\n awarenessProtocol.encodeAwarenessUpdate(provider.awareness, [\n provider.doc.clientID\n ])\n )\n websocket.send(encoding.toUint8Array(encoderAwarenessState))\n }\n }\n provider.emit('status', [{\n status: 'connecting'\n }])\n }\n}\n\n/**\n * @param {WebsocketProvider} provider\n * @param {ArrayBuffer} buf\n */\nconst broadcastMessage = (provider, buf) => {\n const ws = provider.ws\n if (provider.wsconnected && ws && ws.readyState === ws.OPEN) {\n ws.send(buf)\n }\n if (provider.bcconnected) {\n bc.publish(provider.bcChannel, buf, provider)\n }\n}\n\n/**\n * Websocket Provider for Yjs. Creates a websocket connection to sync the shared document.\n * The document name is attached to the provided url. I.e. the following example\n * creates a websocket connection to http://localhost:1234/my-document-name\n *\n * @example\n * import * as Y from 'yjs'\n * import { WebsocketProvider } from 'y-websocket'\n * const doc = new Y.Doc()\n * const provider = new WebsocketProvider('http://localhost:1234', 'my-document-name', doc)\n *\n * @extends {ObservableV2<{ 'connection-close': (event: CloseEvent | null, provider: WebsocketProvider) => any, 'status': (event: { status: 'connected' | 'disconnected' | 'connecting' }) => any, 'connection-error': (event: Event, provider: WebsocketProvider) => any, 'sync': (state: boolean) => any }>}\n */\nexport class WebsocketProvider extends ObservableV2 {\n /**\n * @param {string} serverUrl\n * @param {string} roomname\n * @param {Y.Doc} doc\n * @param {object} opts\n * @param {boolean} [opts.connect]\n * @param {awarenessProtocol.Awareness} [opts.awareness]\n * @param {Object<string,string>} [opts.params] specify url parameters\n * @param {Array<string>} [opts.protocols] specify websocket protocols\n * @param {typeof WebSocket} [opts.WebSocketPolyfill] Optionall provide a WebSocket polyfill\n * @param {number} [opts.resyncInterval] Request server state every `resyncInterval` milliseconds\n * @param {number} [opts.maxBackoffTime] Maximum amount of time to wait before trying to reconnect (we try to reconnect using exponential backoff)\n * @param {boolean} [opts.disableBc] Disable cross-tab BroadcastChannel communication\n */\n constructor (serverUrl, roomname, doc, {\n connect = true,\n awareness = new awarenessProtocol.Awareness(doc),\n params = {},\n protocols = [],\n WebSocketPolyfill = WebSocket,\n resyncInterval = -1,\n maxBackoffTime = 2500,\n disableBc = false\n } = {}) {\n super()\n // ensure that serverUrl does not end with /\n while (serverUrl[serverUrl.length - 1] === '/') {\n serverUrl = serverUrl.slice(0, serverUrl.length - 1)\n }\n this.serverUrl = serverUrl\n this.bcChannel = serverUrl + '/' + roomname\n this.maxBackoffTime = maxBackoffTime\n /**\n * The specified url parameters. This can be safely updated. The changed parameters will be used\n * when a new connection is established.\n * @type {Object<string,string>}\n */\n this.params = params\n this.protocols = protocols\n this.roomname = roomname\n this.doc = doc\n this._WS = WebSocketPolyfill\n this.awareness = awareness\n this.wsconnected = false\n this.wsconnecting = false\n this.bcconnected = false\n this.disableBc = disableBc\n this.wsUnsuccessfulReconnects = 0\n this.messageHandlers = messageHandlers.slice()\n /**\n * @type {boolean}\n */\n this._synced = false\n /**\n * @type {WebSocket?}\n */\n this.ws = null\n this.wsLastMessageReceived = 0\n /**\n * Whether to connect to other peers or not\n * @type {boolean}\n */\n this.shouldConnect = connect\n\n /**\n * @type {number}\n */\n this._resyncInterval = 0\n if (resyncInterval > 0) {\n this._resyncInterval = /** @type {any} */ (setInterval(() => {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n // resend sync step 1\n const encoder = encoding.createEncoder()\n encoding.writeVarUint(encoder, messageSync)\n syncProtocol.writeSyncStep1(encoder, doc)\n this.ws.send(encoding.toUint8Array(encoder))\n }\n }, resyncInterval))\n }\n\n /**\n * @param {ArrayBuffer} data\n * @param {any} origin\n */\n this._bcSubscriber = (data, origin) => {\n if (origin !== this) {\n const encoder = readMessage(this, new Uint8Array(data), false)\n if (encoding.length(encoder) > 1) {\n bc.publish(this.bcChannel, encoding.toUint8Array(encoder), this)\n }\n }\n }\n /**\n * Listens to Yjs updates and sends them to remote peers (ws and broadcastchannel)\n * @param {Uint8Array} update\n * @param {any} origin\n */\n this._updateHandler = (update, origin) => {\n if (origin !== this) {\n const encoder = encoding.createEncoder()\n encoding.writeVarUint(encoder, messageSync)\n syncProtocol.writeUpdate(encoder, update)\n broadcastMessage(this, encoding.toUint8Array(encoder))\n }\n }\n this.doc.on('update', this._updateHandler)\n /**\n * @param {any} changed\n * @param {any} _origin\n */\n this._awarenessUpdateHandler = ({ added, updated, removed }, _origin) => {\n const changedClients = added.concat(updated).concat(removed)\n const encoder = encoding.createEncoder()\n encoding.writeVarUint(encoder, messageAwareness)\n encoding.writeVarUint8Array(\n encoder,\n awarenessProtocol.encodeAwarenessUpdate(awareness, changedClients)\n )\n broadcastMessage(this, encoding.toUint8Array(encoder))\n }\n this._exitHandler = () => {\n awarenessProtocol.removeAwarenessStates(\n this.awareness,\n [doc.clientID],\n 'app closed'\n )\n }\n if (env.isNode && typeof process !== 'undefined') {\n process.on('exit', this._exitHandler)\n }\n awareness.on('update', this._awarenessUpdateHandler)\n this._checkInterval = /** @type {any} */ (setInterval(() => {\n if (\n this.wsconnected &&\n messageReconnectTimeout <\n time.getUnixTime() - this.wsLastMessageReceived\n ) {\n // no message received in a long time - not even your own awareness\n // updates (which are updated every 15 seconds)\n closeWebsocketConnection(this, /** @type {WebSocket} */ (this.ws), null)\n }\n }, messageReconnectTimeout / 10))\n if (connect) {\n this.connect()\n }\n }\n\n get url () {\n const encodedParams = url.encodeQueryParams(this.params)\n return this.serverUrl + '/' + this.roomname +\n (encodedParams.length === 0 ? '' : '?' + encodedParams)\n }\n\n /**\n * @type {boolean}\n */\n get synced () {\n return this._synced\n }\n\n set synced (state) {\n if (this._synced !== state) {\n this._synced = state\n // @ts-ignore\n this.emit('synced', [state])\n this.emit('sync', [state])\n }\n }\n\n destroy () {\n if (this._resyncInterval !== 0) {\n clearInterval(this._resyncInterval)\n }\n clearInterval(this._checkInterval)\n this.disconnect()\n if (env.isNode && typeof process !== 'undefined') {\n process.off('exit', this._exitHandler)\n }\n this.awareness.off('update', this._awarenessUpdateHandler)\n this.doc.off('update', this._updateHandler)\n super.destroy()\n }\n\n connectBc () {\n if (this.disableBc) {\n return\n }\n if (!this.bcconnected) {\n bc.subscribe(this.bcChannel, this._bcSubscriber)\n this.bcconnected = true\n }\n // send sync step1 to bc\n // write sync step 1\n const encoderSync = encoding.createEncoder()\n encoding.writeVarUint(encoderSync, messageSync)\n syncProtocol.writeSyncStep1(encoderSync, this.doc)\n bc.publish(this.bcChannel, encoding.toUint8Array(encoderSync), this)\n // broadcast local state\n const encoderState = encoding.createEncoder()\n encoding.writeVarUint(encoderState, messageSync)\n syncProtocol.writeSyncStep2(encoderState, this.doc)\n bc.publish(this.bcChannel, encoding.toUint8Array(encoderState), this)\n // write queryAwareness\n const encoderAwarenessQuery = encoding.createEncoder()\n encoding.writeVarUint(encoderAwarenessQuery, messageQueryAwareness)\n bc.publish(\n this.bcChannel,\n encoding.toUint8Array(encoderAwarenessQuery),\n this\n )\n // broadcast local awareness state\n const encoderAwarenessState = encoding.createEncoder()\n encoding.writeVarUint(encoderAwarenessState, messageAwareness)\n encoding.writeVarUint8Array(\n encoderAwarenessState,\n awarenessProtocol.encodeAwarenessUpdate(this.awareness, [\n this.doc.clientID\n ])\n )\n bc.publish(\n this.bcChannel,\n encoding.toUint8Array(encoderAwarenessState),\n this\n )\n }\n\n disconnectBc () {\n // broadcast message with local awareness state set to null (indicating disconnect)\n const encoder = encoding.createEncoder()\n encoding.writeVarUint(encoder, messageAwareness)\n encoding.writeVarUint8Array(\n encoder,\n awarenessProtocol.encodeAwarenessUpdate(this.awareness, [\n this.doc.clientID\n ], new Map())\n )\n broadcastMessage(this, encoding.toUint8Array(encoder))\n if (this.bcconnected) {\n bc.unsubscribe(this.bcChannel, this._bcSubscriber)\n this.bcconnected = false\n }\n }\n\n disconnect () {\n this.shouldConnect = false\n this.disconnectBc()\n if (this.ws !== null) {\n closeWebsocketConnection(this, this.ws, null)\n }\n }\n\n connect () {\n this.shouldConnect = true\n if (!this.wsconnected && this.ws === null) {\n setupWS(this)\n this.connectBc()\n }\n }\n}\n"],"names":["encoding","syncProtocol","awarenessProtocol","decoding","authProtocol","math","time","bc","ObservableV2","env","url"],"mappings":"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"}