WebSocket Provider for Yjs
The Websocket Provider implements a classical client server model. Clients connect to a single endpoint over Websocket. The server distributes awareness information and document updates among clients.
The Websocket Provider is a solid choice if you want a central source that handles authentication and authorization. Websockets also send header information and cookies, so you can use existing authentication mechanisms with this server.
- Supports cross-tab communication. When you open the same document in the same browser, changes on the document are exchanged via cross-tab communication (Broadcast Channel and localStorage as fallback).
- Supports exchange of awareness information (e.g. cursors).
This repository forks y-websocket to authenticate with against a PrograMaker backend.
For this to work, the environment variable API_HOST has to be set to the backend's URL (for example http://internal-backend-node:8888).
import*asYfrom'yjs'import{WebsocketProvider}from'y-websocket'constdoc=newY.Doc()constwsProvider=newWebsocketProvider('ws://localhost:1234','my-roomname',doc)wsProvider.on('status',event=>{console.log(event.status)// logs "connected" or "disconnected"})The WebSocket provider requires a WebSocket object to create connection to a server. You can polyfill WebSocket support in Node.js using the ws package.
constwsProvider=newWebsocketProvider('ws://localhost:1234','my-roomname',doc,{WebSocketPolyfill: require('ws')})import{WebsocketProvider}from'y-websocket'- Create a new websocket-provider instance. As long as this provider, or the connected ydoc, is not destroyed, the changes will be synced to other clients via the connected server. Optionally, you may specify a configuration object. The following default values of wsOpts can be overwritten.
wsProvider = new WebsocketProvider(serverUrl: string, room: string, ydoc: Y.Doc [, wsOpts: WsOpts])wsOpts={// Set this to `false` if you want to connect manually using wsProvider.connect()connect: true,// Specify a query-string that will be url-encoded and attached to the `serverUrl`// I.e. params = { auth: "bearer" } will be transformed to "?auth=bearer"params: {},// Object<string,string>// You may polyill the Websocket object (https://developer.mozilla.org/en-US/docs/Web/API/WebSocket).// E.g. In nodejs, you could specify WebsocketPolyfill = require('ws')WebsocketPolyfill: Websocket,// Specify an existing Awareness instance - see https://github.com/yjs/y-protocolsawareness: newawarenessProtocol.Awareness(ydoc)}- True if this instance is currently connected to the server.
- True if this instance is currently connecting to the server.
- If false, the client will not try to reconnect.
- True if this instance is currently communicating to other browser-windows via BroadcastChannel.
- True if this instance is currently connected and synced with the server./dd>
wsProvider.disconnect() - Disconnect from the server and don't try to reconnect.
- Establish a websocket connection to the websocket-server. Call this if you recently disconnected or if you set wsOpts.connect = false.
- Destroy this wsProvider instance. Disconnects from the server and removes all event handlers.
- Add an event listener for the sync event that is fired when the client received content from the server.
wsProvider.wsconnected: booleanwsProvider.wsconnecting: booleanwsProvider.shouldConnect: booleanwsProvider.bcconnected: booleanwsProvider.synced: booleanwsProvider.connect()wsProvider.destroy()wsProvider.on('sync', function(isSynced: boolean))Start a y-websocket server:
HOST=localhost PORT=1234 npx y-websocket-serverSince npm symlinks the y-websocket-server executable from your local ./node_modules/.bin folder, you can simply run npx. The PORT environment variable already defaults to 1234, and HOST defaults to localhost.
Persist document updates in a LevelDB database.
See LevelDB Persistence for more info.
HOST=localhost PORT=1234 YPERSISTENCE=./dbDir node ./node_modules/y-websocket/bin/server.jsSend a debounced callback to an HTTP server (POST) on document update. Note that this implementation doesn't implement a retry logic in case the CALLBACK_URL does not work.
Can take the following ENV variables:
CALLBACK_URL: Callback server URLCALLBACK_DEBOUNCE_WAIT: Debounce time between callbacks (in ms). Defaults to 2000 msCALLBACK_DEBOUNCE_MAXWAIT: Maximum time to wait before callback. Defaults to 10 secondsCALLBACK_TIMEOUT: Timeout for the HTTP call. Defaults to 5 secondsCALLBACK_OBJECTS: JSON of shared objects to get data ('{"SHARED_OBJECT_NAME":"SHARED_OBJECT_TYPE}')
CALLBACK_URL=http://localhost:3000/ CALLBACK_OBJECTS='{"prosemirror":"XmlFragment"}' npm startThis sends a debounced callback to localhost:3000 2 seconds after receiving an update (default DEBOUNCE_WAIT) with the data of an XmlFragment named "prosemirror" in the body.
The MIT License © Kevin Jahns