Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Kevin Jahns
    @dmonad
    @geralt1_gitlab You can open a ticket on discuss.yjs.dev
    1 reply
    Dan Steingart
    @dansteingart
    has anyone made an updated ace binding? thanks.
    Vinicius Zaramella
    @vzaramel
    Hi guys, Is there a way of get the initial update sync in chunks instead of a single update? Or split a update in smaller chunks?
    The reason I am asking is that I am implementing a persistence provider to work with Cloudflare Workers Durable Object, but their storage only accepts a max of 32Kb per value in the kv store.
    Kevin Jahns
    @dmonad
    @vzaramel No that's impossible unfortunately, you need to split messages yourself (by implementing your own protocol to chunk messages and merge them together at some point)
    Vitali Lovich
    @vlovich
    Hi. I'm trying to use y-websocket with Cloudflare Workers DO acting as the server. Normally I obtain a WebSocket in Workers by issuing a fetch with an upgrade. Is that something I can bridge into y-websocket or do I have to do everything custom? I'm assuming the latter - do I just build on top of y-protocols instead?
    Vitali Lovich
    @vlovich
    Oh I see @vzaramel might be doing something similar
    Kevin Jahns
    @dmonad
    @vlovich I would just build on y-protocols. But you can implement your own instead - it is not very complicated.
    @dansteingart Sorry for the late answer. To my knowledge, there is no Ace binding that works with the latest Yjs.
    atng
    @atng

    Hello everyone :)
    I've just started with yjs and have found it amazing! I'm particularly interested in the subdocuments feature, but i'm facing some issues with the example in the docs (https://docs.yjs.dev/api/subdocuments) - it doesn't seem to be working right.

    Here's what the docs say

    A new feature that was introduced in Yjs@13.4.0 is that all documents are given a GUID. The documents are identified with GUIDs and used as a room-name to sync documents. This allows you to duplicate data in the document structure.

    Here's some sample code:

    const rootDoc = new Y.Doc();const doc = new Y.Doc(); doc.getMap().set("data", "some initial data");
    rootDoc.getMap().set("file.txt", doc);
    const copy = new Y.Doc({ guid: doc.guid });
    rootDoc.getMap().set("copy.txt", copy);
    console.log(copy.getMap().get("data"));
    console.log(doc.getMap().get("data"));

    Here's the output:

    undefined
    some initial data

    Shouldn't the output be the same? Or did I miss something here? Any help is appreciated! Thank you.

    Kevin Jahns
    @dmonad
    @atng You probably didn't assign a provider. Yjs documents need providers to sync, otherwise they don't know about each other..
    atng
    @atng
    @kev Oh right! I've tried it with y-websocket - I'm assuming that we need to hookup the updates with a custom provider that updates all the subdocs with the same guid on update?
    atng
    @atng
    @dmonad ^ oops tagged the wrong person there. Thank you!
    coffice1
    @coffice1
    how to use Y.Text for paragraphs? or each paragraph use on Y.Text and wrap them in a Y.Array?
    each paragraph uses one Y.Text
    coffice1
    @coffice1
    i'm using yjs demo server. after restart server and reopen browser, the ydoc content is still there. where is it stored? how to clear it?
    16 replies
    kapil verma
    @kapv89

    i have built an application in which users can create diagrams for a specific domain, and work on them collaboratively. This application uses yjs + y-websocket for this. Awareness is used heavily for different features.

    I want to build a feature where a diagram can be made accessible publically, but everyone viewing the diagram loads a local copy of the diagram and can interact with it.

    I want to re-use the core engine which is used by the diagram editor, and load the yDoc in it. The problem is that awareness is used to keep track of collaborator cursor, object drags, object highlights and so on.

    I want an awareness implementation that operates locally. Is there some way to make this work?

    mustafaKamal-fe
    @mustafaKamal-fe
    Hello friends,
    I want to subscribe Yjs events to update my React state!!!
    So users will type down using a rich text editor. The output is xmlFragment. Now i would like to represent the output in HTML using React. However, I want to update only parts that have changed using to re-render only thoes parts. Is there any solution for this problem
    Joshua Fontany
    @joshuafontany
    @dmonad I got a friend to help webpack the QuillDelta library, but I thought I might ask again. Is there anything in the Yjs package that would allow me to generate a Delta of two Y.Texts, so that I can apply it to the document in my y-tiddlywiki Binding? My wiki software (Tiddlywiki) runs on immutable objects behind the scenes, and I get an object with a "title" and a set of named "fields" on each update from the user. I can easily get the "new strings", but then applying them to their bound Y.Maps is easy on straight up string replacement, but complicated if that field of the Y.Map holds a Y.Text.
    kapil verma
    @kapv89

    i have built an application in which users can create diagrams for a specific domain, and work on them collaboratively. This application uses yjs + y-websocket for this. Awareness is used heavily for different features.

    I want to build a feature where a diagram can be made accessible publically, but everyone viewing the diagram loads a local copy of the diagram and can interact with it.

    I want to re-use the core engine which is used by the diagram editor, and load the yDoc in it. The problem is that awareness is used to keep track of collaborator cursor, object drags, object highlights and so on.

    I want an awareness implementation that operates locally. Is there some way to make this work?

    by the way I managed to do this by building a local-awareness-provider :)

    Brian E. Granger
    @ellisonbg
    @dmonad congrts on the new move functionality in Yjs - that is pretty amazing!
    Kevin Jahns
    @dmonad
    Thanks @ellisonbg :)
    Nigel Gilbert
    @micrology
    I use awareness in a similar sort of visual editor for PRSM: the code is at https://github.com/micrology/prsm (look at the bottom of js/prsm.js)
    Braden Wiggins
    @FractalHQ
    @nodumo @whawker any chance either of you can provide some insight into how you solved the issue with a new connection causing the starting content to be duplicated / doc being replaced?
    Braden Wiggins
    @FractalHQ
    I've been trying to figure out how to avoid re-setting the default monaco editor state when new users join a room, but the initial state of all of the YJS objects are undefined when new users join even though the initial user has already set them.
    So I can't use them to populate local state
    Braden Wiggins
    @FractalHQ
    I can't seem to get any sort of on('connect' event to fire on provider or awareness which I imagine would help me wait for the data
    this is the webrtc provider btw, can't find much info on its events
    Braden Wiggins
    @FractalHQ
    provider.on('synced' also never fires
    Braden Wiggins
    @FractalHQ
    ok I'm making progress now with observeDeep
    Braden Wiggins
    @FractalHQ
    Got it working! 😅
    mustafaKamal-fe
    @mustafaKamal-fe

    Hello friends,
    I want to subscribe Yjs events to update my React state!!!
    So users will type down using a rich text editor. The output is xmlFragment. Now i would like to represent the output in HTML using React. However, I want to update only parts that have changed using to re-render only thoes parts. Is there any solution for this problem

    any Ideas ?

    FindAPattern
    @FindAPattern
    @mustafaKamal-fe You can use an approach like this: https://syncedstore.org.
    I personally don't like using proxies, because it's very slow, so I use a different approach of binding my yjs objects to their computed JSON in a state tree, and then using useSyncExternalStoreWithSelector to update the react tree efficiently.
    FindAPattern
    @FindAPattern

    @dmonad I'm running into an issue with using yjs for a collaborative text editing tool. When I inspect the IndexedDB database, it appears that the initial state update is getting stored twice. The documents can be quite large, so I don't want to waste all of this space.

    That said, I'm trying to understand encodeStateAsUpdate's second parameter, as it appears to exist to mitigate this issue, but it isn't operating the way I expect. My understanding is that if you supply the same state as the target object, you should get a very small or nonexistent update, but that's not happening.

    Example code for testing:

    const docA = new Y.Doc();
    const docB = new Y.Doc();
    
    docB.on('update', (update: Uint8Array) => {
      console.log('update', update);
    });
    
    docA.getMap().set('name', new Y.Text('El Pollo Diablo'));
    docB.getMap().set('name', new Y.Text('El Pollo Diablo'));
    
    const docBState = Y.encodeStateVector(docB);
    const update = Y.encodeStateAsUpdate(docA, docBState);
    
    console.log('before update');
    Y.applyUpdate(docB, update);
    console.log('after update');
    
    console.log(docA.getMap().toJSON());
    console.log(docB.getMap().toJSON());

    Output:

    update Uint8Array(42) [
        1,   2, 168, 154, 142, 211,   8,   0, 39,   1,
        0,   4, 110,  97, 109, 101,   2,   4,  0, 168,
      154, 142, 211,   8,   0,  15,  69, 108, 32,  80,
      111, 108, 108, 111,  32,  68, 105,  97, 98, 108,
      111,   0
    ]
    before update
    update Uint8Array(50) [
        1,   2, 152, 205, 189, 164,   9,   0,  39,   1,   0,
        4, 110,  97, 109, 101,   2,   4,   0, 152, 205, 189,
      164,   9,   0,  15,  69, 108,  32,  80, 111, 108, 108,
      111,  32,  68, 105,  97,  98, 108, 111,   1, 168, 154,
      142, 211,   8,   1,   0,  16
    ]
    after update
    { name: 'El Pollo Diablo' }
    { name: 'El Pollo Diablo' }
    So I guess my question is... what is the purpose of the second parameter in encodeStateAsUpdate?
    (Also, thank you for making this incredible library. I converted a considerably large React + Redux application to use it, and it just worked. No defects. No unexpected issues.)
    FindAPattern
    @FindAPattern
    My guess is that it's not doing an actual tree diff, which is somewhat problematic, as it makes restoring snapshots from JSON a bit difficult (since the local document size will increase very quickly).
    Kevin Jahns
    @dmonad

    Yjs never performs a diff between states (we don't even include any kind of diffing library in Yjs). It simply exchanges operations and transforms them so that everyone ends up with the same content.

    In your case, you simply perform the operation: set YText("El Pollo Diabolo") in a Y.Map with the key 'name'. One of the edits will win and overwrite the other state. Instead, you should perform operations on the Y.Text if you want more granular merges.

    The API is documented on the documentation website: https://docs.yjs.dev/api/document-updates
    FindAPattern
    @FindAPattern
    Thanks Kevin. The issue I'm dealing with is a bit higher level. All of the information in the application is syncing just fine. This was just a simple use case for me to figure out how to synchronize snapshots.
    I have a WebSocket w/ Redis provider setup, but I want to treat the Redis storage as entirely ephemeral, so I'm cleaning it up every time all clients disconnect.
    When all clients disconnect, I'm saving the entire document as JSON to a Postgres database. If a client connects again in the future, the server loads the JSON document and converts it to a YJS map, which it then syncs with the client's local IndexedDB document.
    Is there a better approach for doing this type of thing?
    I guess the ideal solution here would be to store the document state vector in Postgres as a binary column. Perhaps that would solve some of these issues.
    Kevin Jahns
    @dmonad
    I recommend to store the document in the Yjs update format in your postgres database (you can still store the json for indexing if needed). This allows you to avoid conflicts with history.
    kapil verma
    @kapv89
    @FindAPattern you can take a look at this repo https://github.com/kapv89/yjs-scalable-ws-backend for persistence to postgres
    Nigel Gilbert
    @micrology
    I'm using the default y-websocket with with default LevelDB persistence adapter. It seems that I could use a postgres database instead (or possibly some other database). Are there any advantages to switching to postgres?
    kapil verma
    @kapv89

    @FindAPattern you can take a look at this repo https://github.com/kapv89/yjs-scalable-ws-backend for persistence to postgres

    @micrology I use the code shared in this repo to set up authentication and persistence via an api endpoint that is protected by an api token

    MarshallChang
    @MarshallChang
    Hi, I'm using y-websocket with slate-yjs , can anyone help me to covert the Uint8Array to utf-8 ? so I can persist the updates into pg and view these operations by java