From 6fd9eec258ce21d4db8cf1e593bb8b891b3f3c50 Mon Sep 17 00:00:00 2001
From: Jure Triglav <juretriglav@gmail.com>
Date: Thu, 18 Mar 2021 09:31:04 +0100
Subject: [PATCH] chore: remove experimental and unused Wax real time
 collaboration

---
 .../wax-collab/src/EditorElements.js          |  96 ++---
 .../wax-collab/src/config/config.js           |  35 +-
 app/components/wax-collab/src/provider.js     | 126 -------
 package.json                                  |   6 +-
 server/app.js                                 |  26 --
 server/wax-collab/server-util.js              | 345 ------------------
 yarn.lock                                     | 204 +----------
 7 files changed, 46 insertions(+), 792 deletions(-)
 delete mode 100644 app/components/wax-collab/src/provider.js
 delete mode 100644 server/wax-collab/server-util.js

diff --git a/app/components/wax-collab/src/EditorElements.js b/app/components/wax-collab/src/EditorElements.js
index b4a5419d60..85fd3a8407 100644
--- a/app/components/wax-collab/src/EditorElements.js
+++ b/app/components/wax-collab/src/EditorElements.js
@@ -1,3 +1,4 @@
+/* stylelint-disable selector-type-no-unknown */
 import { css } from 'styled-components'
 
 /* All styles regarding ProseMirror surface and elements */
@@ -6,19 +7,21 @@ export default css`
   .ProseMirror {
     counter-reset: footnote;
     font-family: ${props => props.theme.fontReading};
+
     &:focus {
       outline: none;
     }
   }
+
   .ProseMirror footnote {
-    font-size: 0;
-    display: inline-block;
-    text-align: center;
-    width: 17px;
-    height: 17px;
     background: black;
     color: white;
     cursor: pointer;
+    display: inline-block;
+    font-size: 0;
+    height: 17px;
+    text-align: center;
+    width: 17px;
   }
 
   h1 {
@@ -30,24 +33,26 @@ export default css`
   p {
     margin-bottom: 1em;
   }
+
   .ProseMirror footnote::after {
-    content: counter(footnote);
-    position: relative;
     bottom: 2px;
-    font-size: 16px;
+    content: counter(footnote);
     counter-increment: footnote;
+    font-size: 16px;
+    position: relative;
   }
+
   hr {
-    padding: 2px 10px;
     border: none;
     margin: 1em 0;
+    padding: 2px 10px;
   }
 
   hr:after {
+    background-color: silver;
     content: '';
     display: block;
     height: 1px;
-    background-color: silver;
     line-height: 2px;
   }
 
@@ -63,11 +68,12 @@ export default css`
   em {
     font-style: italic;
   }
+
   blockquote {
-    padding-left: 1em;
     border-left: 3px solid #eee;
     margin-left: 0;
     margin-right: 0;
+    padding-left: 1em;
   }
 
   img {
@@ -82,25 +88,25 @@ export default css`
   /* Tables */
 
   table {
+    border: 1px solid #eee;
     border-collapse: initial;
     border-spacing: 0;
     border-width: 0 thin thin 0;
-    border: 1px solid #eee;
-    table-layout: fixed;
-    width: 100%;
     margin: 0;
     overflow: hidden;
     page-break-inside: avoid;
+    table-layout: fixed;
+    width: 100%;
   }
 
   th,
   td {
     border: 1px solid #eee;
+    box-sizing: border-box;
     /*width: 200px;*/
     padding: 2px 5px;
-    vertical-align: top;
-    box-sizing: border-box;
     position: relative;
+    vertical-align: top;
   }
 
   .tableWrapper {
@@ -108,31 +114,32 @@ export default css`
   }
 
   .column-resize-handle {
+    background-color: #adf;
+    bottom: 0;
+    pointer-events: none;
     position: absolute;
     right: -2px;
     top: 0;
-    bottom: 0;
     width: 4px;
     z-index: 20;
-    background-color: #adf;
-    pointer-events: none;
   }
 
   .ProseMirror.resize-cursor {
     cursor: ew-resize;
     cursor: col-resize;
   }
+
   /* Give selected cells a blue overlay */
   .selectedCell:after {
-    z-index: 2;
-    position: absolute;
+    background: rgba(200, 200, 255, 0.4);
+    bottom: 0;
     content: '';
     left: 0;
+    pointer-events: none;
+    position: absolute;
     right: 0;
     top: 0;
-    bottom: 0;
-    background: rgba(200, 200, 255, 0.4);
-    pointer-events: none;
+    z-index: 2;
   }
 
   /* placeholder */
@@ -140,8 +147,8 @@ export default css`
     color: #aaa;
     float: left;
     font-style: italic;
-    pointer-events: none;
     height: 0;
+    pointer-events: none;
   }
 
   p.empty-node:first-child::before {
@@ -158,8 +165,8 @@ export default css`
     caret-color: inherit;
     color: gray;
     display: inline-block;
-    font-weight: 400;
     font-style: normal;
+    font-weight: 400;
     line-height: 1em;
     width: 0;
   }
@@ -177,8 +184,8 @@ export default css`
   }
 
   span.deletion {
-    text-decoration: line-through;
     color: red;
+    text-decoration: line-through;
   }
 
   span.insertion {
@@ -201,11 +208,11 @@ export default css`
   }
 
   [data-track]::before {
-    content: '';
-    position: absolute;
     border-left: 2px solid blue;
-    left: -10px;
+    content: '';
     height: 100%;
+    left: -10px;
+    position: absolute;
   }
 
   li[data-track]::before,
@@ -218,34 +225,7 @@ export default css`
     border-radius: 3px 3px 0 0;
   }
 
-  // Cursor
-
-  .ProseMirror-yjs-cursor {
-    position: absolute;
-    border-left: black;
-    border-left-style: solid;
-    border-left-width: 2px;
-    border-color: orange;
-    height: 1.33em;
-    word-break: normal;
-    pointer-events: none;
-  }
-  .ProseMirror-yjs-cursor > div {
-    position: relative;
-    top: -1.05em;
-    left: -2px;
-    font-size: 13px;
-    background-color: rgb(250, 129, 0);
-    font-style: lighter;
-    font-weight: normal;
-    line-height: normal;
-    user-select: none;
-    color: white;
-    padding-left: 2px;
-    padding-right: 2px;
-  }
-
   code {
-    font-family: monospace, monospace;
+    font-family: monospace;
   }
 `
diff --git a/app/components/wax-collab/src/config/config.js b/app/components/wax-collab/src/config/config.js
index 203896dcd0..635d0b5ac3 100644
--- a/app/components/wax-collab/src/config/config.js
+++ b/app/components/wax-collab/src/config/config.js
@@ -1,14 +1,3 @@
-// import * as Y from 'yjs'
-// import { WebsocketProvider } from 'y-websocket'
-// import {
-//   ySyncPlugin,
-//   yCursorPlugin,
-//   yUndoPlugin,
-//   undo,
-//   redo,
-// } from 'y-prosemirror'
-
-// import * as sharedTypes from '../provider'
 import { emDash, ellipsis } from 'prosemirror-inputrules'
 
 import {
@@ -41,23 +30,6 @@ import invisibles, {
   // paragraph,
 } from '@guardian/prosemirror-invisibles'
 
-// const ydoc = new Y.Doc();
-// const provider = new WebsocketProvider(
-//   "ws://localhost:1234",
-//   "waxingandwaning",
-//   ydoc
-// );
-
-// const colors = [{ light: '#6eeb8333', dark: '#6eeb83' },
-// { light: '#ecd44433', dark: '#ecd444' }]
-// const type = ydoc.getXmlFragment("prosemirror");
-
-// const opts = [sharedTypes.prosemirrorEditorContent, { permanentUserData: sharedTypes.permanentUserData, colors }]
-// const opts = [sharedTypes.prosemirrorEditorContent]
-// sharedTypes.awareness.setLocalStateField('user', _.sample(users))
-
-// console.log(ydoc, provider, type);
-
 export default {
   MenuService: [
     {
@@ -76,12 +48,7 @@ export default {
 
   ShortCutsService: {},
 
-  PmPlugins: [
-    invisibles([hardBreak()]),
-    // ySyncPlugin(...opts),
-    // yCursorPlugin(sharedTypes.awareness),
-    // yUndoPlugin(),
-  ],
+  PmPlugins: [invisibles([hardBreak()])],
 
   services: [
     new PlaceholderService(),
diff --git a/app/components/wax-collab/src/provider.js b/app/components/wax-collab/src/provider.js
deleted file mode 100644
index 9f6227fcc9..0000000000
--- a/app/components/wax-collab/src/provider.js
+++ /dev/null
@@ -1,126 +0,0 @@
-import * as Y from 'yjs'
-// import { WebrtcProvider } from 'y-webrtc'
-import { WebsocketProvider } from 'y-websocket'
-// import { IndexeddbPersistence, storeState } from 'y-indexeddb'
-
-const websocketUrl = 'ws://localhost:3000/w'
-
-const lastSnapshot = null
-
-/**
- * @param {Y.Item} item
- * @return {boolean}
- */
-const gcFilter = item =>
-  !Y.isParentOf(prosemirrorEditorContent, item) ||
-  (lastSnapshot && (lastSnapshot.sv.get(item.id.client) || 0) <= item.id.clock)
-
-// const suffix = '-v3'
-
-// export const versionDoc = new Y.Doc()
-// this websocket provider doesn't connect
-// export const versionWebsocketProvider = new WebsocketProvider(websocketUrl, 'yjs-website-version' + suffix, versionDoc, { connect: false })
-// versionWebsocketProvider.connectBc() // only connect via broadcastchannel
-// export const versionIndexeddbPersistence = new IndexeddbPersistence('test', versionDoc)
-// export const versionType = versionDoc.getArray('versions')
-
-const token = localStorage.getItem('token')
-export const doc = new Y.Doc({ gcFilter })
-// console.log(doc.awarenessStates)
-export const websocketProvider = new WebsocketProvider(
-  websocketUrl,
-  'test-server-given',
-  doc,
-  { params: { id: doc.clientID, token } },
-)
-// export const webrtcProvider = new WebrtcProvider('yjs-website' + suffix, doc)
-export const { awareness } = websocketProvider
-
-// export const indexeddbPersistence = new IndexeddbPersistence('yjs-website' + suffix, doc)
-
-export const prosemirrorEditorContent = doc.getXmlFragment('prosemirror')
-
-// versionIndexeddbPersistence.on('synced', () => {
-//   lastSnapshot = versionType.length > 0 ? Y.decodeSnapshot(versionType.get(0).snapshot) : Y.emptySnapshot
-//   versionType.observe(() => {
-//     if (versionType.length > 0) {
-//       const nextSnapshot = Y.decodeSnapshot(versionType.get(0).snapshot)
-//       undoManager.clear()
-//       Y.tryGc(nextSnapshot.ds, doc.store, gcFilter)
-//       lastSnapshot = nextSnapshot
-//       storeState(indexeddbPersistence)
-//     }
-//   })
-// })
-
-class LocalRemoteUserData extends Y.PermanentUserData {
-  /**
-   * @param {number} clientid
-   * @return {string}
-   */
-  getUserByClientId(clientid) {
-    return super.getUserByClientId(clientid) || 'remote'
-  }
-  /**
-   * @param {Y.ID} id
-   * @return {string}
-   */
-  getUserByDeletedId(id) {
-    return super.getUserByDeletedId(id) || 'remote'
-  }
-}
-
-// const lodash = require('lodash')
-
-// Const demo users
-
-// const users = [
-//   { name: 'James', color: '#f44336', colorLight: 'e57373' },
-//   { name: 'Lydia', color: '#E91E63', colorLight: '#F06292' },
-//   { name: 'Bill', color: '#9C27B0', colorLight: '#BA68C8' },
-//   { name: 'Farnshuw', color: '#03A9F4', colorLight: '#4FC3F7' },
-//   { name: 'Giselde', color: '#009688', colorLight: '#4DB6AC' },
-//   { name: 'Patrick', color: '#D4E157', colorLight: '#E6EE9C' },
-// ]
-
-export const permanentUserData = new LocalRemoteUserData(
-  doc,
-  doc.getMap('users'),
-)
-// console.log('MAP OF USERS', doc.getMap('users'))
-
-//  versionIndexeddbPersistence.whenSynced.then(() => {
-// permanentUserData.setUserMapping(doc, doc.clientID, 'local', lodash.sample(users))
-// })
-
-/**
- * An array of draw element.
- * A draw element is a Y.Map that has a type attribute. We will support only type "path", but you could also define type "text", or type "rectangle".
- *
- * @type {Y.Array<Y.Map<Y.Array|String|object>>}
- */
-export const drawingContent = doc.getArray('drawing')
-
-let undoManager = null
-
-export const setUndoManager = nextUndoManager => {
-  if (undoManager) {
-    undoManager.clear()
-  }
-  undoManager = nextUndoManager
-}
-
-// @ts-ignore
-window.ydoc = doc
-// @ts-ignore
-// window.versionDoc = versionDoc
-// @ts-ignore
-window.awareness = awareness
-// @ts-ignore
-// window.webrtcProvider = webrtcProvider
-// @ts-ignore
-window.websocketProvider = websocketProvider
-// @ts-ignore
-// window.indexeddbPersistence = indexeddbPersistence
-// @ts-ignore
-window.prosemirrorEditorContent = prosemirrorEditorContent
diff --git a/package.json b/package.json
index b35d602f81..d51c68f939 100644
--- a/package.json
+++ b/package.json
@@ -110,6 +110,7 @@
     "passport": "^0.4.1",
     "passport-orcid": "0.0.4",
     "prop-types": "15.7.2",
+    "prosemirror-inputrules": "^1.1.3",
     "pubsweet": "^5.1.14",
     "pubsweet-client": "^10.2.5",
     "pubsweet-server": "^13.11.6",
@@ -143,10 +144,7 @@
     "xpub-edit": "2.6.11",
     "xpub-journal": "0.1.0",
     "xpub-validators": "0.0.28",
-    "xpub-with-context": "0.2.0",
-    "y-protocols": "1.0.1",
-    "y-websocket": "1.3.1",
-    "yjs": "13.3.0"
+    "xpub-with-context": "0.2.0"
   },
   "devDependencies": {
     "@babel/core": "7.11.6",
diff --git a/server/app.js b/server/app.js
index ec76a6a675..8ca5ea0c69 100644
--- a/server/app.js
+++ b/server/app.js
@@ -17,9 +17,7 @@ const registerComponents = require('pubsweet-server/src/register-components') //
 const compression = require('compression')
 
 // Wax Collab requirements
-const WebSocket = require('ws')
 const EventEmitter = require('events')
-const wsUtils = require('./wax-collab/server-util.js')
 const gqlApi = require('./graphql')
 
 const configureApp = app => {
@@ -126,10 +124,6 @@ const configureApp = app => {
       .json({ message: err.message })
   })
 
-  // Set up a separate websocket for Wax-Collab
-  const wss = new WebSocket.Server({ noServer: true })
-  wss.on('connection', (conn, req) => wsUtils.setupWSConnection(conn, req))
-
   // Actions to perform when the HTTP server starts listening
   app.onListen = async server => {
     const { addSubscriptions } = require('./subscriptions')
@@ -142,26 +136,6 @@ const configureApp = app => {
     server.on('upgrade', (request, socket, head, ...rest) => {
       if (request.url === '/subscriptions') {
         serverProxy.emit('upgrade', request, socket, head, ...rest)
-      } else {
-        let user = null
-
-        if (request.headers.cookie) {
-          // const cookies = cookie.parse(request.headers.cookie)
-          // const user = cookies.user_identifier
-        }
-
-        // TODO: Do real auth for Wax-collab
-        user = 'test' // shortcut
-
-        if (!user) {
-          // console.log('Failed to authenticate', user)
-          socket.destroy()
-          return
-        }
-
-        wss.handleUpgrade(request, socket, head, ws => {
-          wss.emit('connection', ws, request)
-        })
       }
     })
 
diff --git a/server/wax-collab/server-util.js b/server/wax-collab/server-util.js
deleted file mode 100644
index f6e4038b37..0000000000
--- a/server/wax-collab/server-util.js
+++ /dev/null
@@ -1,345 +0,0 @@
-/* eslint-disable */
-const Y = require('yjs')
-const syncProtocol = require('y-protocols/dist/sync.cjs')
-const awarenessProtocol = require('y-protocols/dist/awareness.cjs')
-
-const encoding = require('lib0/dist/encoding.cjs')
-const decoding = require('lib0/dist/decoding.cjs')
-const mutex = require('lib0/dist/mutex.cjs')
-const map = require('lib0/dist/map.cjs')
-const url = require('lib0/dist/url.cjs')
-const time = require('lib0/dist/time.cjs')
-
-const wsReadyStateConnecting = 0
-const wsReadyStateOpen = 1
-const wsReadyStateClosing = 2 // eslint-disable-line
-const wsReadyStateClosed = 3 // eslint-disable-line
-
-const _ = require('lodash')
-
-// disable gc when using snapshots!
-const gcEnabled = process.env.GC !== 'false' && process.env.GC !== '0'
-const persistenceDir = process.env.YPERSISTENCE
-/**
- * @type {{bindState: function(string,WSSharedDoc):void, writeState:function(string,WSSharedDoc):Promise<any>}|null}
- */
-let persistence = null
-if (typeof persistenceDir === 'string') {
-  // @ts-ignore
-  const { LevelDbPersistence } = require('y-leveldb')
-  persistence = new LevelDbPersistence(persistenceDir)
-}
-
-/**
- * @param {{bindState: function(string,WSSharedDoc):void,
- * writeState:function(string,WSSharedDoc):Promise<any>}|null} persistence_
- */
-exports.setPersistence = persistence_ => {
-  persistence = persistence_
-}
-
-/**
- * @type {Map<string,WSSharedDoc>}
- */
-const docs = new Map()
-
-const messageSync = 0
-const messageAwareness = 1
-const messageAuth = 2
-
-/**
- * @param {Uint8Array} update
- * @param {any} origin
- * @param {WSSharedDoc} doc
- */
-const updateHandler = (update, origin, doc) => {
-  const encoder = encoding.createEncoder()
-  encoding.writeVarUint(encoder, messageSync)
-  syncProtocol.writeUpdate(encoder, update)
-  const message = encoding.toUint8Array(encoder)
-  doc.conns.forEach((_, conn) => send(doc, conn, message))
-}
-
-class WSSharedDoc extends Y.Doc {
-  /**
-   * @param {string} name
-   */
-  constructor(name) {
-    super({ gc: gcEnabled })
-    this.name = name
-    this.mux = mutex.createMutex()
-    /**
-     * Maps from conn to set of controlled user ids. Delete all user ids from awareness when this conn is closed
-     * @type {Map<Object, Set<number>>}
-     */
-    this.conns = new Map()
-    /**
-     * @type {awarenessProtocol.Awareness}
-     */
-    this.awareness = new awarenessProtocol.Awareness(this)
-    this.awareness.setLocalState(null)
-    /**
-     * @param {{ added: Array<number>, updated: Array<number>, removed: Array<number> }} changes
-     * @param {Object | null} conn Origin is the connection that made the change
-     */
-    const awarenessChangeHandler = ({ added, updated, removed }, conn) => {
-      const changedClients = added.concat(updated, removed)
-      if (conn !== null) {
-        const connControlledIDs = /** @type {Set<number>} */ (this.conns.get(
-          conn,
-        ))
-        if (connControlledIDs !== undefined) {
-          added.forEach(clientID => {
-            connControlledIDs.add(clientID)
-          })
-          removed.forEach(clientID => {
-            connControlledIDs.delete(clientID)
-          })
-        }
-      }
-      // broadcast awareness update
-      const encoder = encoding.createEncoder()
-      encoding.writeVarUint(encoder, messageAwareness)
-      encoding.writeVarUint8Array(
-        encoder,
-        awarenessProtocol.encodeAwarenessUpdate(this.awareness, changedClients),
-      )
-      const buff = encoding.toUint8Array(encoder)
-      this.conns.forEach((_, c) => {
-        send(this, c, buff)
-      })
-    }
-    this.awareness.on('change', awarenessChangeHandler)
-    this.on('update', updateHandler)
-  }
-}
-
-/**
- * @param {any} conn
- * @param {WSSharedDoc} doc
- * @param {Uint8Array} message
- */
-const messageListener = (conn, doc, message) => {
-  const encoder = encoding.createEncoder()
-  const decoder = decoding.createDecoder(message)
-  const messageType = decoding.readVarUint(decoder)
-  switch (messageType) {
-    case messageSync:
-      console.log('SYNCING NOW')
-      console.log('AWARENESS ON SYNC', doc.awareness)
-      encoding.writeVarUint(encoder, messageSync)
-      syncProtocol.readSyncMessage(decoder, encoder, doc, null)
-      if (encoding.length(encoder) > 1) {
-        send(doc, conn, encoding.toUint8Array(encoder))
-      }
-      break
-    case messageAwareness: {
-      console.log('I HAVE RECEIVED AWARENESS MESSAGE')
-      awarenessProtocol.applyAwarenessUpdate(
-        doc.awareness,
-        decoding.readVarUint8Array(decoder),
-        conn,
-      )
-      break
-    }
-    case messageAuth: {
-      // awarenessProtocol.applyAwarenessUpdate(doc.awareness, decoding.readVarUint8Array(decoder), conn)
-
-      break
-    }
-  }
-}
-
-/**
- * @param {WSSharedDoc} doc
- * @param {any} conn
- */
-const closeConn = (doc, conn) => {
-  if (doc.conns.has(conn)) {
-    /**
-     * @type {Set<number>}
-     */
-    // @ts-ignore
-    const controlledIds = doc.conns.get(conn)
-    doc.conns.delete(conn)
-    awarenessProtocol.removeAwarenessStates(
-      doc.awareness,
-      Array.from(controlledIds),
-      null,
-    )
-    if (doc.conns.size === 0 && persistence !== null) {
-      // if persisted, we store state and destroy ydocument
-      persistence.writeState(doc.name, doc).then(() => {
-        doc.destroy()
-      })
-      docs.delete(doc.name)
-    }
-  }
-  conn.close()
-}
-
-/**
- * @param {WSSharedDoc} doc
- * @param {any} conn
- * @param {Uint8Array} m
- */
-const send = (doc, conn, m) => {
-  if (
-    conn.readyState !== wsReadyStateConnecting &&
-    conn.readyState !== wsReadyStateOpen
-  ) {
-    closeConn(doc, conn)
-  }
-  try {
-    conn.send(
-      m,
-      /** @param {any} err */ err => {
-        err != null && closeConn(doc, conn)
-      },
-    )
-  } catch (e) {
-    closeConn(doc, conn)
-  }
-}
-
-const pingTimeout = 30000
-
-async function getUserFromToken(token) {
-  const { User } = require('@pubsweet/models')
-  const { token: tokenHelper } = require('pubsweet-server/src/authentication')
-  const userId = await new Promise((resolve, reject) => {
-    tokenHelper.verify(token, (_, id) => {
-      if (!id) {
-        reject(new Error('Bad auth token'))
-      }
-
-      resolve(id)
-    })
-  })
-
-  const user = await User.find(userId)
-  return user
-}
-
-const colors = require('./colors')
-/**
- * @param {any} conn
- * @param {any} req
- * @param {any} opts
- */
-exports.setupWSConnection = async (
-  conn,
-  req,
-  { docName = req.url.slice(1).split('?')[0], gc = true } = {},
-) => {
-  conn.binaryType = 'arraybuffer'
-
-  const { token } = url.decodeQueryParams(req.url) + 'false'
-
-  // For the purpose of this demo, let's also allow unauthenticated users
-  let user
-  try {
-    user = await getUserFromToken(token)
-  } catch (e) {
-    console.log('Assigning random username to client')
-    const names = require('./names')
-    user = { username: _.sample(names) }
-  }
-
-  console.log(user)
-  // console.log(conn)
-  const connectingClientId = Number(url.decodeQueryParams(req.url).id) // to get the client id and set its stuff
-
-  // get doc, create if it does not exist yet
-  const doc = map.setIfUndefined(docs, docName, () => {
-    const doc = new WSSharedDoc(docName)
-    doc.gc = gc
-    if (persistence !== null) {
-      persistence.bindState(docName, doc)
-    }
-    docs.set(docName, doc)
-    console.log(doc.awareness)
-    return doc
-  })
-  doc.conns.set(conn, new Set())
-  // listen and reply to events
-  conn.on(
-    'message',
-    /** @param {ArrayBuffer} message */ message =>
-      messageListener(conn, doc, new Uint8Array(message)),
-  )
-  conn.on('close', () => {
-    closeConn(doc, conn)
-  })
-  // Check if connection is still alive
-  let pongReceived = true
-  const pingInterval = setInterval(() => {
-    if (!pongReceived) {
-      if (doc.conns.has(conn)) {
-        closeConn(doc, conn)
-      }
-      clearInterval(pingInterval)
-    } else if (doc.conns.has(conn)) {
-      pongReceived = false
-      try {
-        conn.ping()
-      } catch (e) {
-        closeConn(doc, conn)
-      }
-    }
-  }, pingTimeout)
-  conn.on('pong', () => {
-    pongReceived = true
-  })
-
-  // send own awarness/user info
-  // Set/initialize the clock for the user too
-  // console.log(doc.awareness.getStates)
-  const currLocalMeta = doc.awareness.meta.get(connectingClientId)
-  const clock = currLocalMeta === undefined ? 10 : currLocalMeta.clock + 1
-  console.log(
-    'Setting state',
-    user.username,
-    'for',
-    connectingClientId,
-    currLocalMeta,
-  )
-  doc.awareness.getStates().set(connectingClientId, {
-    user: { name: user.username, color: _.sample(colors) },
-  })
-  doc.awareness.meta.set(connectingClientId, {
-    clock,
-    lastUpdated: time.getUnixTime(),
-  })
-
-  // end of own user info
-
-  // const encoder = encoding.createEncoder()
-  // encoding.writeVarUint(encoder, messageAuth)
-  // encoding.writeVarUint8Array(encoder,
-  // syncProtocol.writeSyncStep1(encoder, { username: 'test', color: 'red', colorLight: 'brown' })
-  // send(doc, conn, encoding.toUint8Array(encoder))
-
-  // send sync step 1
-  const encoder = encoding.createEncoder()
-  encoding.writeVarUint(encoder, messageSync)
-  syncProtocol.writeSyncStep1(encoder, doc)
-  send(doc, conn, encoding.toUint8Array(encoder))
-
-  // doc.awareness.getStates().set()
-  const awarenessStates = doc.awareness.getStates()
-  // console.log(awarenessStates)
-
-  if (awarenessStates.size > 0) {
-    const encoder = encoding.createEncoder()
-    encoding.writeVarUint(encoder, messageAwareness)
-    encoding.writeVarUint8Array(
-      encoder,
-      awarenessProtocol.encodeAwarenessUpdate(
-        doc.awareness,
-        Array.from(awarenessStates.keys()),
-      ),
-    )
-    send(doc, conn, encoding.toUint8Array(encoder))
-  }
-}
diff --git a/yarn.lock b/yarn.lock
index b1ebe36e52..b85107fb1a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3892,28 +3892,6 @@ abbrev@1:
   resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
   integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
 
-abstract-leveldown@^6.2.1:
-  version "6.3.0"
-  resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a"
-  integrity sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==
-  dependencies:
-    buffer "^5.5.0"
-    immediate "^3.2.3"
-    level-concat-iterator "~2.0.0"
-    level-supports "~1.0.0"
-    xtend "~4.0.0"
-
-abstract-leveldown@~6.2.1, abstract-leveldown@~6.2.3:
-  version "6.2.3"
-  resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb"
-  integrity sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==
-  dependencies:
-    buffer "^5.5.0"
-    immediate "^3.2.3"
-    level-concat-iterator "~2.0.0"
-    level-supports "~1.0.0"
-    xtend "~4.0.0"
-
 accepts@^1.3.5, accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
   version "1.3.7"
   resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
@@ -5781,7 +5759,7 @@ buffer@^4.3.0:
     ieee754 "^1.1.4"
     isarray "^1.0.0"
 
-buffer@^5.2.0, buffer@^5.5.0, buffer@^5.6.0:
+buffer@^5.2.0:
   version "5.7.1"
   resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
   integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
@@ -7637,14 +7615,6 @@ defer-to-connect@^2.0.0:
   resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
   integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
 
-deferred-leveldown@~5.3.0:
-  version "5.3.0"
-  resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058"
-  integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==
-  dependencies:
-    abstract-leveldown "~6.2.1"
-    inherits "^2.0.3"
-
 define-properties@^1.1.2, define-properties@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -8214,16 +8184,6 @@ encodeurl@~1.0.2:
   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
   integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
 
-encoding-down@^6.3.0:
-  version "6.3.0"
-  resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b"
-  integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==
-  dependencies:
-    abstract-leveldown "^6.2.1"
-    inherits "^2.0.3"
-    level-codec "^9.0.0"
-    level-errors "^2.0.0"
-
 encoding@^0.1.11:
   version "0.1.13"
   resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
@@ -8342,7 +8302,7 @@ enzyme@^3.7.0:
     rst-selector-parser "^2.2.3"
     string.prototype.trim "^1.2.1"
 
-errno@^0.1.3, errno@~0.1.1, errno@~0.1.7:
+errno@^0.1.3, errno@~0.1.7:
   version "0.1.8"
   resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"
   integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==
@@ -11036,11 +10996,6 @@ image-q@^1.1.1:
   resolved "https://registry.yarnpkg.com/image-q/-/image-q-1.1.1.tgz#fc84099664460b90ca862d9300b6bfbbbfbf8056"
   integrity sha1-/IQJlmRGC5DKhi2TALa/u7+/gFY=
 
-immediate@^3.2.3:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266"
-  integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==
-
 immer@8.0.1:
   version "8.0.1"
   resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656"
@@ -11909,11 +11864,6 @@ isomorphic-fetch@^2.1.1:
     node-fetch "^1.0.1"
     whatwg-fetch ">=0.10.0"
 
-isomorphic.js@^0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/isomorphic.js/-/isomorphic.js-0.2.2.tgz#4c76fb70d3e207123dead08675ba97eb75f5615a"
-  integrity sha512-tWhdHK5vam77zCkNKjpI8vWSrcVmlBeJIlxXgTiGaapgifQr0CfLHuPqMiZhjrI/K71X/aXaJZqUbkHZzg06Hg==
-
 isstream@0.1.x, isstream@~0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@@ -12796,88 +12746,6 @@ left-pad@^1.3.0:
   resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
   integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==
 
-level-codec@^9.0.0:
-  version "9.0.2"
-  resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc"
-  integrity sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==
-  dependencies:
-    buffer "^5.6.0"
-
-level-concat-iterator@~2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263"
-  integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==
-
-level-errors@^2.0.0, level-errors@~2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8"
-  integrity sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==
-  dependencies:
-    errno "~0.1.1"
-
-level-iterator-stream@~4.0.0:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz#7ceba69b713b0d7e22fcc0d1f128ccdc8a24f79c"
-  integrity sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==
-  dependencies:
-    inherits "^2.0.4"
-    readable-stream "^3.4.0"
-    xtend "^4.0.2"
-
-level-js@^5.0.0:
-  version "5.0.2"
-  resolved "https://registry.yarnpkg.com/level-js/-/level-js-5.0.2.tgz#5e280b8f93abd9ef3a305b13faf0b5397c969b55"
-  integrity sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==
-  dependencies:
-    abstract-leveldown "~6.2.3"
-    buffer "^5.5.0"
-    inherits "^2.0.3"
-    ltgt "^2.1.2"
-
-level-packager@^5.1.0:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939"
-  integrity sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==
-  dependencies:
-    encoding-down "^6.3.0"
-    levelup "^4.3.2"
-
-level-supports@~1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d"
-  integrity sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==
-  dependencies:
-    xtend "^4.0.2"
-
-level@^6.0.1:
-  version "6.0.1"
-  resolved "https://registry.yarnpkg.com/level/-/level-6.0.1.tgz#dc34c5edb81846a6de5079eac15706334b0d7cd6"
-  integrity sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==
-  dependencies:
-    level-js "^5.0.0"
-    level-packager "^5.1.0"
-    leveldown "^5.4.0"
-
-leveldown@^5.4.0:
-  version "5.6.0"
-  resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-5.6.0.tgz#16ba937bb2991c6094e13ac5a6898ee66d3eee98"
-  integrity sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==
-  dependencies:
-    abstract-leveldown "~6.2.1"
-    napi-macros "~2.0.0"
-    node-gyp-build "~4.1.0"
-
-levelup@^4.3.2:
-  version "4.4.0"
-  resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6"
-  integrity sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==
-  dependencies:
-    deferred-leveldown "~5.3.0"
-    level-errors "~2.0.0"
-    level-iterator-stream "~4.0.0"
-    level-supports "~1.0.0"
-    xtend "~4.0.0"
-
 leven@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
@@ -12903,13 +12771,6 @@ levn@^0.3.0, levn@~0.3.0:
     prelude-ls "~1.1.2"
     type-check "~0.3.2"
 
-lib0@^0.2.28, lib0@^0.2.31, lib0@^0.2.32, lib0@^0.2.35:
-  version "0.2.40"
-  resolved "https://registry.yarnpkg.com/lib0/-/lib0-0.2.40.tgz#7c89c2a7a89f9caaa0a04eaecb944d8e90a731b3"
-  integrity sha512-bKJxwll8MdwTTL3Siut6L+FjyF5sewXRE7noDTsRquEYy3Xi1UjtdEMZu46iuTvw9nQ/9p+gKkh1GxL2Kdaphw==
-  dependencies:
-    isomorphic.js "^0.2.2"
-
 liftoff@3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3"
@@ -13365,11 +13226,6 @@ lru-cache@^6.0.0:
   dependencies:
     yallist "^4.0.0"
 
-ltgt@^2.1.2:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5"
-  integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=
-
 luxon@^1.25.0:
   version "1.26.0"
   resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.26.0.tgz#d3692361fda51473948252061d0f8561df02b578"
@@ -14129,11 +13985,6 @@ nanomatch@^1.2.9:
     snapdragon "^0.8.1"
     to-regex "^3.0.1"
 
-napi-macros@~2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b"
-  integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==
-
 native-url@^0.2.6:
   version "0.2.6"
   resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.2.6.tgz#ca1258f5ace169c716ff44eccbddb674e10399ae"
@@ -14261,11 +14112,6 @@ node-forge@^0.10.0:
   resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
   integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==
 
-node-gyp-build@~4.1.0:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb"
-  integrity sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==
-
 node-int64@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@@ -16225,7 +16071,7 @@ prosemirror-history@^1.0.0, prosemirror-history@^1.1.3:
     prosemirror-transform "^1.0.0"
     rope-sequence "^1.3.0"
 
-prosemirror-inputrules@^1.0.0, prosemirror-inputrules@^1.1.2:
+prosemirror-inputrules@^1.0.0, prosemirror-inputrules@^1.1.2, prosemirror-inputrules@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.1.3.tgz#93f9199ca02473259c30d7e352e4c14022d54638"
   integrity sha512-ZaHCLyBtvbyIHv0f5p6boQTIJjlD6o2NPZiEaZWT2DA+j591zS29QQEMT4lBqwcLW3qRSf7ZvoKNbf05YrsStw==
@@ -17269,7 +17115,7 @@ readable-stream@1.1.x:
     isarray "0.0.1"
     string_decoder "~0.10.x"
 
-readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
+readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0:
   version "3.6.0"
   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
   integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@@ -21233,44 +21079,11 @@ xss@^1.0.8:
     commander "^2.20.3"
     cssfilter "0.0.10"
 
-xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1:
+xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
   integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
 
-y-leveldb@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/y-leveldb/-/y-leveldb-0.1.0.tgz#8b60c1af020252445875ebc70d52666017bcb038"
-  integrity sha512-sMuitVrsAUNh+0b66I42nAuW3lCmez171uP4k0ePcTAJ+c+Iw9w4Yq3wwiyrDMFXBEyQSjSF86Inc23wEvWnxw==
-  dependencies:
-    level "^6.0.1"
-    lib0 "^0.2.31"
-
-y-protocols@1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/y-protocols/-/y-protocols-1.0.1.tgz#7855c900039a02b369590b8ae78bc6e1cbc13c9f"
-  integrity sha512-QP3fCM7c2gGfUi2nqf8gspyO4VW23zv3kNqPNdD3wNxMbuNQenMyoDVZYEo12jzR4RQ3aaDfPK62Sf31SVOmfg==
-  dependencies:
-    lib0 "^0.2.28"
-
-y-protocols@^1.0.0:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/y-protocols/-/y-protocols-1.0.4.tgz#810978c6172474be87457c3bcd669e529c5ba3a1"
-  integrity sha512-5/Hd6DJ5Y2SlbqLIKq86BictdOS0iAcWJZCVop8MKqx0XWwA+BbMn4538n4Z0CGjFMUGnG1kGzagk3BKGz5SvQ==
-  dependencies:
-    lib0 "^0.2.35"
-
-y-websocket@1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/y-websocket/-/y-websocket-1.3.1.tgz#19e00ad9a4a491c9d0d14768547f437522e7a98f"
-  integrity sha512-pt4lyFz1jlJObl5IN2r7YWyzsRRdpQXGc2WbBXlsyMamZPID4y+MITeIpEr8n95I0d/Bx28uzgH4qhhb/3QmZg==
-  dependencies:
-    lib0 "^0.2.31"
-    y-leveldb "^0.1.0"
-    y-protocols "^1.0.0"
-  optionalDependencies:
-    ws "^6.2.1"
-
 y18n@^3.2.1:
   version "3.2.2"
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696"
@@ -21370,13 +21183,6 @@ yauzl@^2.10.0:
     buffer-crc32 "~0.2.3"
     fd-slicer "~1.1.0"
 
-yjs@13.3.0:
-  version "13.3.0"
-  resolved "https://registry.yarnpkg.com/yjs/-/yjs-13.3.0.tgz#e43f3297b01dbafd7c21077cd1f651db93e06494"
-  integrity sha512-QdWZljN7OkAKen3VJ9P7sXwjuw+00WRXvmjZvgT28yMgxGnZ8w2LYP4GynuneLn53I6gud1PxB5zCeVODQC/dg==
-  dependencies:
-    lib0 "^0.2.32"
-
 yocto-queue@^0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
-- 
GitLab