From 405216549871cc9e4bfbb0edf3f7ead2caaabef8 Mon Sep 17 00:00:00 2001 From: Hans Pagel Date: Fri, 25 Sep 2020 23:22:21 +0200 Subject: [PATCH] add basic yjs extension with baked in web rtc support (wip) --- .../Examples/Collaboration/index.spec.js | 5 + .../demos/Examples/Collaboration/index.vue | 46 +++++++ docs/src/docPages/examples/collaboration.md | 4 +- docs/src/links.yaml | 5 +- packages/extension-yjs/index.ts | 27 ++++ packages/extension-yjs/package.json | 22 ++++ yarn.lock | 120 +++++++++++++++++- 7 files changed, 221 insertions(+), 8 deletions(-) create mode 100644 docs/src/demos/Examples/Collaboration/index.spec.js create mode 100644 docs/src/demos/Examples/Collaboration/index.vue create mode 100644 packages/extension-yjs/index.ts create mode 100644 packages/extension-yjs/package.json diff --git a/docs/src/demos/Examples/Collaboration/index.spec.js b/docs/src/demos/Examples/Collaboration/index.spec.js new file mode 100644 index 000000000..8e0e94031 --- /dev/null +++ b/docs/src/demos/Examples/Collaboration/index.spec.js @@ -0,0 +1,5 @@ +context('/examples/collaboration', () => { + before(() => { + cy.visit('/examples/collaboration') + }) +}) diff --git a/docs/src/demos/Examples/Collaboration/index.vue b/docs/src/demos/Examples/Collaboration/index.vue new file mode 100644 index 000000000..f1c0192ac --- /dev/null +++ b/docs/src/demos/Examples/Collaboration/index.vue @@ -0,0 +1,46 @@ + + + diff --git a/docs/src/docPages/examples/collaboration.md b/docs/src/docPages/examples/collaboration.md index 3c6373905..501fe3003 100644 --- a/docs/src/docPages/examples/collaboration.md +++ b/docs/src/docPages/examples/collaboration.md @@ -1,3 +1,5 @@ # Collaboration - \ No newline at end of file + + + diff --git a/docs/src/links.yaml b/docs/src/links.yaml index de4e586a8..817748d80 100644 --- a/docs/src/links.yaml +++ b/docs/src/links.yaml @@ -117,9 +117,8 @@ # - title: CodeBlockHighlight # link: /api/extensions/code-block-highlight # draft: true - # - title: Collaboration - # link: /api/extensions/collaboration - # draft: true + - title: Collaboration + link: /api/extensions/collaboration - title: Document link: /api/extensions/document - title: HardBreak diff --git a/packages/extension-yjs/index.ts b/packages/extension-yjs/index.ts new file mode 100644 index 000000000..550ca6a02 --- /dev/null +++ b/packages/extension-yjs/index.ts @@ -0,0 +1,27 @@ +import { Extension } from '@tiptap/core' +import { keymap } from 'prosemirror-keymap' +import { + redo, undo, yCursorPlugin, ySyncPlugin, yUndoPlugin, +} from 'y-prosemirror' +import { WebrtcProvider } from 'y-webrtc' +import * as Y from 'yjs' + +const ydoc = new Y.Doc() +const provider = new WebrtcProvider('tiptap', ydoc) +const type = ydoc.getXmlFragment('prosemirror') + +export default new Extension() + .name('yjs') + .plugins(() => { + return [ + ySyncPlugin(type), + yCursorPlugin(provider.awareness), + yUndoPlugin(), + keymap({ + 'Mod-z': undo, + 'Mod-y': redo, + 'Mod-Shift-z': redo, + }), + ] + }) + .create() diff --git a/packages/extension-yjs/package.json b/packages/extension-yjs/package.json new file mode 100644 index 000000000..f185f1363 --- /dev/null +++ b/packages/extension-yjs/package.json @@ -0,0 +1,22 @@ +{ + "name": "@tiptap/extension-yjs", + "version": "1.0.0", + "source": "index.ts", + "main": "dist/tiptap-extension-yjs.js", + "umd:main": "dist/tiptap-extension-yjs.umd.js", + "module": "dist/tiptap-extension-yjs.mjs", + "unpkg": "dist/tiptap-extension-yjs.js", + "jsdelivr": "dist/tiptap-extension-yjs.js", + "files": [ + "src", + "dist" + ], + "peerDependencies": { + "@tiptap/core": "2.x" + }, + "dependencies": { + "y-prosemirror": "^0.3.7", + "y-webrtc": "^10.1.6", + "yjs": "^13.3.2" + } +} diff --git a/yarn.lock b/yarn.lock index 869185df9..9faa4a860 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2114,6 +2114,19 @@ magic-string "^0.25.2" resolve "^1.11.0" +"@rollup/plugin-commonjs@^15.0.0": + version "15.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-15.1.0.tgz#1e7d076c4f1b2abf7e65248570e555defc37c238" + integrity sha512-xCQqz4z/o0h2syQ7d9LskIMvBSH4PX5PjYdpSSvgS+pQik3WahkQVNWg3D8XJeYjZoVWnIUQYDghuEMRGrmQYQ== + dependencies: + "@rollup/pluginutils" "^3.1.0" + commondir "^1.0.1" + estree-walker "^2.0.1" + glob "^7.1.6" + is-reference "^1.2.1" + magic-string "^0.25.7" + resolve "^1.17.0" + "@rollup/plugin-json@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.1.0.tgz#54e09867ae6963c593844d8bd7a9c718294496f3" @@ -2132,6 +2145,18 @@ is-module "^1.0.0" resolve "^1.11.1" +"@rollup/plugin-node-resolve@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-9.0.0.tgz#39bd0034ce9126b39c1699695f440b4b7d2b62e6" + integrity sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.17.0" + "@rollup/pluginutils@^3.0.0", "@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" @@ -2370,6 +2395,13 @@ dependencies: "@types/node" "*" +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + "@types/sinonjs__fake-timers@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e" @@ -5830,6 +5862,11 @@ estree-walker@^1.0.1: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== +estree-walker@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.1.tgz#f8e030fb21cefa183b44b7ad516b747434e7a3e0" + integrity sha512-tF0hv+Yi2Ot1cwj9eYHtxC0jB9bmjacjQs6ZBTj82H8JwUywFuc+7E83NWfNMwHXZc11mjfFcVXPe9gEP4B8dg== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -6550,6 +6587,11 @@ gensync@^1.0.0-beta.1: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== +get-browser-rtc@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-browser-rtc/-/get-browser-rtc-1.0.2.tgz#bbcd40c8451a7ed4ef5c373b8169a409dd1d11d9" + integrity sha1-u81AyEUaftTvXDc7gWmkCd0dEdk= + get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -8108,7 +8150,7 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== -is-reference@^1.1.2: +is-reference@^1.1.2, is-reference@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== @@ -8251,6 +8293,11 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +isomorphic.js@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/isomorphic.js/-/isomorphic.js-0.1.4.tgz#6cc878773b0d895261a1b022e6863d564fcccd28" + integrity sha512-t9zbgkjE7f9f2M6OSW49YEq0lUrSdAllBbWFUZoeck/rnnFae6UlhmDtXWs48VJY3ZpryCoZsRiAiKD44hPIGQ== + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -8570,6 +8617,13 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lib0@^0.2.28, lib0@^0.2.32, lib0@^0.2.33: + version "0.2.33" + resolved "https://registry.yarnpkg.com/lib0/-/lib0-0.2.33.tgz#dd759c489d416344efe065c534bccf3ce4925d3e" + integrity sha512-Pnm8FzjUr+aTYkEu2A20c1EfVHla8GbVX+GXn6poxx0gcmEuCs+XszjLmtEbI9xYOoI/83xVi7VOIoyHgOO87w== + dependencies: + isomorphic.js "^0.1.3" + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -8927,7 +8981,7 @@ magic-string@^0.22.4: dependencies: vlq "^0.2.2" -magic-string@^0.25.2: +magic-string@^0.25.2, magic-string@^0.25.7: version "0.25.7" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== @@ -11434,6 +11488,11 @@ querystringify@^2.1.1: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== +queue-microtask@^1.1.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.1.4.tgz#40841ace4356b48b35b5ea61a2e1fe0a23c59ce1" + integrity sha512-eY/4Obve9cE5FK8YvC1cJsm5cr7XvAurul8UtBDJ2PR1p5NmAwHtvAt5ftcLtwYRCUKNhxCneZZlxmUDFoSeKA== + quick-lru@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" @@ -11449,7 +11508,7 @@ ramda@~0.26.1: resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.3, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== @@ -12175,6 +12234,13 @@ rollup@^1.32.1: "@types/node" "*" acorn "^7.1.0" +rollup@^2.26.11: + version "2.28.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.28.2.tgz#599ec4978144a82d8a8ec3d37670a8440cb04e4b" + integrity sha512-8txbsFBFLmm9Xdt4ByTOGa9Muonmc8MfNjnGAR8U8scJlF1ZW7AgNZa7aqBXaKtlvnYP/ab++fQIq9dB9NWUbg== + optionalDependencies: + fsevents "~2.1.2" + rope-sequence@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.2.tgz#a19e02d72991ca71feb6b5f8a91154e48e3c098b" @@ -12550,6 +12616,17 @@ simple-get@^4.0.0: once "^1.3.1" simple-concat "^1.0.0" +simple-peer@^9.7.2: + version "9.7.2" + resolved "https://registry.yarnpkg.com/simple-peer/-/simple-peer-9.7.2.tgz#8cd9cb156bf456ad9c3d379119f0c39dfb3b20f7" + integrity sha512-xeMyxa9B4V0eA6mf17fVr8nm2QhAYFu+ZZv8zkSFFTjJETGF227CshwobrIYZuspJglMD63egcevQXGOrTIsuA== + dependencies: + debug "^4.0.1" + get-browser-rtc "^1.0.0" + queue-microtask "^1.1.0" + randombytes "^2.0.3" + readable-stream "^3.4.0" + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -14656,7 +14733,7 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" -ws@^7.2.3: +ws@^7.2.0, ws@^7.2.3: version "7.3.1" resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== @@ -14694,6 +14771,34 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +y-prosemirror@^0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/y-prosemirror/-/y-prosemirror-0.3.7.tgz#df929ceacb3e35c568db9f1a5a36b0515b3732fc" + integrity sha512-9jj+BU5T608AjER3uwXkbYKhms6hLNivJDU6/CUAafaM4A1qrDE6blAPe4WOL8f1/oMQ7ZdcXMZpIsoemFHXzg== + dependencies: + "@rollup/plugin-commonjs" "^15.0.0" + "@rollup/plugin-node-resolve" "^9.0.0" + lib0 "^0.2.33" + rollup "^2.26.11" + +y-protocols@^1.0.0: + 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-webrtc@^10.1.6: + version "10.1.6" + resolved "https://registry.yarnpkg.com/y-webrtc/-/y-webrtc-10.1.6.tgz#1bc33f044c7e4ad1ad8a8311550f05b5aa95a43b" + integrity sha512-b3pTIv9LcPuMb4nbDT3/kkgmcuQoTrBmaPbBqPH1LJMzI8HwYnMK8p5r0fBQJBI0YRor+i8BT15Evv1nQBP0zg== + dependencies: + lib0 "^0.2.32" + simple-peer "^9.7.2" + y-protocols "^1.0.0" + optionalDependencies: + ws "^7.2.0" + y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" @@ -14790,3 +14895,10 @@ yauzl@^2.10.0, yauzl@^2.4.2: dependencies: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" + +yjs@^13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yjs/-/yjs-13.3.2.tgz#80377d7a1e3af8d9611e95b7bf1a96d3203cda6c" + integrity sha512-f4R9wK4Pn0FDrNR++mjaW4mbC/qsFHzZaDicva1yN3IMrlUuwQ6qt3HEUc4DMiAkjETGB07LyhxbQ9YgNenk8Q== + dependencies: + lib0 "^0.2.32"