by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Callum Atwal
    @callum-atwal

    On the server js side, you'll want to require the https module let https = require('https');

    search for the line where it does http.createServer and change to https.createServer which takes one extra parameter for your keys. (I'm using y-webrtc and had to do this for the signalling server, heres my code)

    const options = {
      cert: fs.readFileSync('/etc/letsencrypt/live/<<DOMAIN>>/fullchain.pem'),
      key: fs.readFileSync('/etc/letsencrypt/live/<<DOMAIN>>/privkey.pem')
    }
    const signalServer = https.createServer(options, (request, response) => {
      response.writeHead(200, { 'Content-Type': 'text/plain' })
      response.end('okay')
    })

    Hope this helps @micrology

    micrology
    @micrology
    @callum-atwal Yes, that was really helpful, and I have got it working. For others wanting to do this, note that in addition to Callum's edits, you will also need to add const fs = require('fs')at the top of server.js. @dmonad This change means that the certificates are hard coded into server.js and that if I were to upgrade y-websocket to a future version, the certificate links will be lost. Possibly something to consider if you extend y-websocket in future?
    Callum Atwal
    @callum-atwal
    Yep forgot the fs require! Glad it worked :)
    Duane Johnson
    @canadaduane
    I used nginx in front of y-websocket and it worked well. Here is the configuration I needed to allow nginx to upgrade a websocket reverse proxy over ssl: https://gist.github.com/canadaduane/18d3868e2a129fc75b78ca5139eaa1dc
    Andrew Milich
    @amilich
    has anyone built a socketio provider that's open-source?
    if not, is the class AbstractConnector still relevant to building a provider?
    Andrew Milich
    @amilich
    I'm trying to create a p2p version of the websocket provider
    Duane Johnson
    @canadaduane
    Oh, neat. So that server nodes can connect to each other?
    Putyahin
    @Putyahin
    Hello. Has anyone tried to use Firebase or another DB to sync Yjs document state between users. Will it work fast enough in collaborative work with using d3.js library. If anyone has some examples I will appreciate sharing some of them. Thank you in advance.
    Moritz Hedtke
    @mohe2015
    Hi, is it currently possible to combine WebrtcProvider and IndexeddbPersistence and if how?
    Callum Atwal
    @callum-atwal
    @mohe2015 i would have a look at the implementation for the yjs website at https://github.com/yjs/website/blob/master/src/sharedTypes.js
    I wasn't personally able to get it working but I wasn't able to spend much time on it - but that might be a clue of how to go about it
    Moritz Hedtke
    @mohe2015
    Thanks a lot for the pointer to that file! I will sleep now but probably report tomorrow whether I was successful.
    Callum Atwal
    @callum-atwal
    No worries, good luck :)
    Moritz Hedtke
    @mohe2015
    Yeah, it seemed to have worked :)
    await indexeddbPersistence.whenSynced may help in some cases I think
    Callum Atwal
    @callum-atwal
    Nice! If you have time, perhaps an edit could be submitted for the README? Just to provide other future developers some clarity on the usage
    Moritz Hedtke
    @mohe2015
    I'm thinking of using this project in a decentralized system. As far as I understand currently the client id is just a random integer. So I would need to replace that with some public key / private key system if I understand correctly to guarantee that the data is from the client? Or is there something I'm missing?
    Andrew Milich
    @amilich
    any way to convert YJS content to json easily?
    Callum Atwal
    @callum-atwal
    what do you mean?
    Andrew Milich
    @amilich
    just serializing a YXML Fragment - but the answer is here :) https://github.com/yjs/yjs/blob/master/README.md
    matrixbot
    @matrixbot
    KB1RD Hello! I've been working on a CRDT of my own for a while. Due to a couple of shortcomings with the version that I have now, I was going to rewrite it with a new algorithm, which is currently just a couple of notes. Upon doing more research, I found Y.js and read the paper. It seemed to satisfy the requirements I had, so I figured that it might be best just to abandon what I have and use Y.js. Just a quick question: The paper seems to indicate that order of elements can be established (if I'm reading it correctly). So, I wrote a simple Y.js script with two documents and I inserted 'a', 'b', and 'c' in three separate operations and I recorded the updates for each. Then, I fed only the updates for 'a' and 'c' to the other document, but the second document then only contained 'a'. Next, I sent 'b' and the second document then read 'abc' as expected. Why is it that if an update in the middle is missing the end is not visible?
    KB1RD Here's my code:
    const Y = require('yjs')
    
    const doc1 = new Y.Doc()
    const doc2 = new Y.Doc()
    
    const ub1 = []
    doc1.on('update', update => {
      ub1.push(update)
    })
    
    doc1.getArray('myarray').insert(0, ['a'])
    doc1.getArray('myarray').insert(1, ['b'])
    doc1.getArray('myarray').insert(2, ['c'])
    Y.applyUpdate(doc2, ub1[0])
    console.log(doc2.getArray('myarray').map(s => s)) // Prints `[ 'a' ]`
    Y.applyUpdate(doc2, ub1[2])
    console.log(doc2.getArray('myarray').map(s => s)) // Prints `[ 'a' ]`
    Y.applyUpdate(doc2, ub1[1])
    console.log(doc2.getArray('myarray').map(s => s)) // Prints `[ 'a', 'b', 'c' ]`
    Winston Fassett
    @WinstonFassett
    I may be off in my understanding somewhere, but you might get results more like you are expecting if you create a separate Y.Doc for each instance. By doing them all from the same doc1, you make them depend on each other, so that update c depends on b depends on a. I believe that's why the second result doesn't have C applied. Because within the doc1 edit "session", i.e. for doc1's randomly generated clientID, YJS records that update C depends on B and effectively waits for it. But if you use separate docs which will create separate client IDs, you should be able to merge the updates from them in any order, such that the ordering would be determined by their client IDs, so you could (I think) end up with them in any order, but the order would be consistent across all docs with the same updates. So in your example above, YJS is preserving the order of the events coming from any single client by tracking their dependencies and applying updates in dependency order.
    István Koren
    @istvank
    Is it correct that the only way to replace an item in Y.Array is by deleting and then inserting!?
    Kevin Jahns
    @dmonad
    @amilich Exactly as @WinstonFassett described. Thanks @WinstonFassett
    @istvank Yep, that's the only way.
    .. trying to catch up with all the discussion threads. Best you ping again if you are still looking for an answer.
    micrology
    @micrology
    Is "Is there a level-db for version 13?" still an open issue?
    denny
    @dennyluan
    Hello! There was mention a while ago about making y-prosemirror play nicely with decorations and transactions. Seeing that using Yjs with our existing PM plugins breaks them (e.g. comments example from PM site), is there any discussion about making y-prosemirror work with decorations/transactions?
    Or is there anyone that is using yjs/PM with those kinds of plugins?
    Kevin Jahns
    @dmonad
    @micrology still not..
    Kevin Jahns
    @dmonad

    @dennyluan For now, you can try not to rely on ProseMirrors position mapping and instead recalculate the position. In the case of comments, you should use Yjs-based relative positions instead of ProseMirror mappings. ProseMirrors position mapping won't work reliably in p2p settings as explained in the blog post.

    The remote cursors implementation is based on relative positions. You can look there for references. Here is another example:

    import { ySyncPluginKey,  absolutePositionToRelativePosition } from 'y-prosemirror'
    const ystate = ySyncPluginKey.getState(view.state)
    // relAnchor is a Yjs based relative position. Relative to the Yjs model. It is basically a pointer to a specific character / paragraph in the Yjs model. You should store the relative positions from the comment, not the absolute positions.
    const relAnchor = absolutePositionToRelativePosition(selection.anchor, ystate.type, ystate.binding.mapping)
    
    // Whenever the ProseMirror state changes, you can compute the absolute position.
    const absoluteAnchor = relativePositionToAbsolutePosition(ydoc, ystate.type, relAnchor, ystate.binding.mapping)
    @micrology Yes, it is still an open issue..
    jini-developer
    @jini-developer
    Hello! What if we want to use multiple tiptap editor on same page how we can handle realtime collaboration using y-websocket provider. Any idea. Thanks
    Eric Meier
    @BitPhinix
    Hi :), I'm sure that has been asked 1000 times here but I can't find anything online so I ask it again:
    Can YJS be used with JSON data? I want to build a collaborative text editor using slate which has a really nested data structure and I'm not sure if YJS is the correct choice of that
    Kevin Jahns
    @dmonad
    @callum-atwal You can find them under provider.room.webrtcConns.get('some-peer-id').peer. Note that room is null until provider.key <promise> resolves. I'm also using y-webrtc for a p2p video chat, so it is definitely possible. You will also find several events in the source code that allow you to listen if a peer joined. You can find my code for listening to peer-changed events here: https://github.com/yjs/y-webcomponents/blob/3ad25e4c5cb80fb9b8166a54b4ff98f576ff00c1/src/conference.js#L131
    Kevin Jahns
    @dmonad

    @jini-developer & @BitPhinix Yjs allows you to nest shared types. Please read some of the examples in the yjs readme.

    @jini-developer The easiest way is to define a type for each editor. I.e. const ytext = ydoc.getText('my fist editor'); const ytext2 = ydoc.getText('my second editor'). But you can also nest the types in an Y.Array. This would allow you to build something like a directory structure of shared types.

    @BitPhinix You basically want to model the Slate data model using shared types. When Slate changes, you apply the same changes to the shared types. And when Yjs changes you apply the changes to Slate. This is what I call a double binding. Yjs supports many editors (many of which have a nested data model) with this approach. It would be best for you to get started by getting to know Yjs's shared types. As your first prototype you can try just to store the Slate model in a Y.Map. Then you can get more granular and start modeling the json format using shared types.

    Mihalache-Mihai
    @Mihalache-Mihai

    Hi,
    I'm currently trying to create a Shared DOM editor using Y-Js. The best example I could find is here: https://github.com/yjs/yjs/tree/dist/Examples/Xml . I tried to start the project, I installed the bower dependencies, but I get an error when trying to start the Xml example (using node index.js): ReferenceError: Y is not defined.

    Also, I looked into the ProseMirror example. The conclusion that I got is that ProseMirror is using the ySyncPlugin for synchronizing only the EditorView. Is it possible to modify the ySyncPlugin in such a way that it will observe over the whole DOM instead of just the EditorView and also not modify the newly components into paragraphs?

    I really appreciate the help!
    Mihai

    Kevin Jahns
    @dmonad

    Hi @Mihalache-Mihai There was a DOM binding for Yjs, that is no longer maintained. It was mainly used to make editors like the closure editor collaborative. But editors that only use the contenteditable API are prone to many issues. Nowadays, we have a lot of awesome editors that abstract contenteditable DOM with a data model. With Yjs you can make these data models collaborative.

    If you still want to use pure DOM for shared editing, I suggest that you try to port the old dom binding https://github.com/yjs/y-dom/

    FYI: Bower is now deprecated. Yjs is still published on bower, because I publish tagged releases. But make sure you are using the latest version of Yjs (>=v13). Yjs uses npm. Try npm install && npm start.

    Nevermind, Yjs is no longer published on bower because I don't maintain a bower file anymore
    RangerMauve
    @RangerMauve
    @dmonad Hey! It was great talking to you on the call! 😁 I had a question about y-js. Does it have any sort of support for sparsely replicating a document? Like only loading a subset of the operations / data instead of loading everything at once?
    Or would something like that be accomplished by having multiple "roots" that have separate operation logs?
    Aslak Hellesøy
    @aslakhellesoy
    Hi @dmonad - I’d like to ise y-webrtc from Node.js. The current implementation makes several assumptions about running in a browser. Would you be interested in a PR that makes it possible to use from Node.js?
    jini-developer
    @jini-developer
    Hi team, I have some questions.
    1. Do we need leveldb for collaboration?
    2. How I can load pre content in tiptap editor from mysql for realtime collaboration. If I load content after editor mount for every new user the pre content will get append in document. Any help.
      Thanks in advance.
    Kevin Jahns
    @dmonad
    Hey @RangerMauve ,
    sorry for the later answer. No, you need to load the whole document. But as you mentioned, it makes sense to put the data in several Yjs documents. Although I find the idea interesting to support lazy loaded content in Yjs.
    Kevin Jahns
    @dmonad
    @aslakhellesoy , yeah sure!
    Kevin Jahns
    @dmonad

    @jini-developer Generally you want to store Yjs document updates instead of the ProseMirror json-encoded document. You can merge Yjs documents, but you can’t simply merge ProseMirror documents. Also have a look at this answer: https://discuss.yjs.dev/t/yjs-overside-the-previous-schema-doc/99/4

    If you want to store the editor content in MySQL, you could simply store the Yjs encoded document in your database. You don't need leveldb for persistence. You just need to store the document somewhere. If you still need to store the JSON encoded document, just store it alongside the Yjs model.