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