Shared space with breakout sessions

Unfortunately I’m still quite confused about some details and workflow between the ydoc, provider, awareness, room… end goal, a shared space with breakout rooms + one main room. So ~ 25 people in a group shared space, everyone sees 1 main document (ie. code from teacher) while working in splitscreen on their own document (alone and/or with others – jumping between them when help is requested).

So far, I’ve sucessfully used 1 Y.Doc (with 4 unique getText id’s), 1 provider (so 1 awareness) and multiple rooms – to serve 4 unique spaces in parallel. Now I could simply hide most of them unless selected… however with the shared awareness across all rooms, it might not be possible to keep track of who is actively looking at/focused on a given room? Ooor this logic should just be passed through the shared awareness of the single provider (which space is focused on)?

Could someone recommend one of the following:

  • separate ydoc, provider, room per space to be viewed (so each client has multiple everything active, regularly switching with them all open, but semi-silent, hidden in the background)
  • 1 ydoc with unique getText() ids, 1 provider, unique rooms, - similar to above, but using awareness to keep track
  • something totally different: ____________

Ideally students could merge the contents of the ‘main’ document (likely read only for them) into their own working document - of which, the document updates provides plenty of examples for merging whole ydoc’s, but what about only merging/applyUpdate from one getText() section to another?

I’ve had checked out other / threads – but Yjs dev moves so rapidly (woohoo) that it seems some discussions from 1 year ago are less relevant, given that the websocket provider can do multi-plexing, allowing for multiple rooms in parallel. Lastly, tried reading up on subdocuments, but not so sure if that’s even necessary for this workflow.

Hi @ffd8!

Happy to see a p5 editor with Yjs!

From what I read, I believe you are looking to represent each text document with a separate Yjs document. It is not possible to merge updates from one getText() to another. If you standardize that all text documents use getText('same name'), then you can merge any two documents.

There is currently no provider that supports multiplexing (sharing multiple documents over a single websocket connection). This makes it easier to implement authentication on a per-document basis. However, I want to introduce sharing subdocuments over a single websockets connection. This feature is also not yet available.

Can you please tell me a bit more about how you want to structure a “space”. I imagine that a space contains several (a variable number?) editors. Users that collaborate on a space want to share awareness information (e.g. cursor information and presence). Not every client has all documents open (what is a breakout session?). How does a user fork a main document?

About the Awareness CRDT: It is just another CRDT implementation that can be shared over one, or more, providers. You could create a separate provider instance to share a single awareness instance. You could also create a single Awareness instance and share that over all the providers.

// sharing a single Awareness instance (per space) over several providers:

import {Awareness} from 'y-protocols/awareness'
const awareness = new Awareness(new Y.Doc()) // ydoc is only needed to create a unique clientID

// when you open an editor..
const ydoc = new Y.Doc()
const provider = new WebsocketProvider(url, room, { awareness }) // share a common awareness instance instead

So if you are looking to have a common awareness instance for one space, then you should just create a single awareness instance and use that for all editors. If you want separate awareness instances for each documents, then others won’t know that others are present in the space unless they connect to the same room.

You could also have one awareness instance for each document (sharing information about who opened a certain document), and another awareness instance for sharing who is available on a space (e.g. over a separate Provider with an empty Y.Doc).

Regarding structuring your space: You can share your complete space using a single Y.Doc, or fragment it into multiple Y.Docs so you can fork & merge them individually. You can either use subdocuments to manage the documents or implement your own protocol. Discussions from a year ago are still relevant if you want to build your own approach for sharing multiple documents.

Hope that makes sense. I know that this flexibility makes everything super complex. Opinionated solutions are easier to work with. Yjs tries not to be unopinionated.

:exploding_head: - haha, but in a wild way.
Looking at my 4up implementation, each editor/panel had it’s own provider, shared ydoc, and used the provider’s awareness. To keep track of overall presence/selected_session of users, sounds like I should add one shared awareness instance, and keep the cursors sync isolated to a provider’s awareness. Will have to think about how global vs session chat would work… something attached to that shared awareness (or just for main shared chat and isolated to the provider of each session). The flexibility is great and of course so many scenarios in how it could be used. Appreciate helping guide best-practice for how it’s intended.

I’m referring to ‘breakout sessions’ as we’ve come to experience it in Zoom/Webex, however I want the user to be present in both the main room and session of their choice (in contrast, videochat moves you from main room into a breakout session of course for webcam/mic reasons). It’s also important that users can quickly jump between each session for helping eachother out = maybe everyone is actually connected to all providers at the same time (just not seeing the editor of a given one) OR everytime they move between sessions, I destroy that provider for them and join them to the selected session’s provider. Asking for help in a session – would then pass a message across the shared awareness provider…?

In terms of the Websocketprovider, guessing it’s no problem for hundreds of provider’s running parallel? Say a given space has ~25 users and maybe 10+ breakout sessions… that’s probably 12 websocket connections (1 or 2 with shared awareness and main panel editor, then 10 or so with just a few users). Hoping that can be multiplied by lots of parallel spaces? Probably just depends on amount of ram the server has?

Here’s a rough sketch of what a space might look like.
LEFT Panel, main sketch (teacher edits, all users connected, can merge from it to their own)
RIGHT Panel, selected session (can hot swap between, userlist/chat, save revision)

Sounds like I should avoid sub-documents for now, as it’s not fully worked out for the websocket provider and instead use multiple providers? I guess that’s the main benefit of subdocs, just one provider for many docs vs 1 per doc… Pretty sure making an own protocol for subdocs is beyond my level.

Sounds like I should avoid sub-documents for now, as it’s not fully worked out for the websocket provider and instead use multiple providers? I guess that’s the main benefit of subdocs, just one provider for many docs vs 1 per doc… Pretty sure making an own protocol for subdocs is beyond my level.

If subdocuments make sense in your application, you should definitely use them. It seems like there is always a top-level document and then several nested documents. The documentation for subdocs contains example code that creates a separate connection for each subdocument. This is exactly what you want.

I also recommend to just have a single provider sharing the awareness state to reduce unnecessary overhead. This could be, for example, the top-level document this is opened by all peers.

Hoping that can be multiplied by lots of parallel spaces? Probably just depends on amount of ram the server has?

Hundreds of connections shouldn’t be a problem if it has enough ram to hold the documents :wink: