YousefED / SyncedStore

SyncedStore CRDT is an easy-to-use library for building live, collaborative applications that sync automatically.
https://syncedstore.org
MIT License
1.71k stars 51 forks source link

What do you think about awareness? #30

Closed jasonm closed 2 years ago

jasonm commented 2 years ago

(Please let me know if there's a better place for discussions like this. Do you prefer e.g. https://discuss.yjs.dev?)

I'm curious how you think about exposing awareness through SyncedStore.

A caveat — as I'm fairly new to Yjs, the answer here may very well be "don't use awareness like that." 😄

In this discuss.yjs.dev thread about Yjs Redux bindings I shared a bit code I've written that I use to provide some facilities reminiscent of redux and react-redux on top of SyncedStore: making the state available throughout the component tree with React context and hooks, and a way of organizing accessors and mutations with names drawn from redux, "selectors" and "actions". I shared a hasty gist here: https://gist.github.com/jasonm/8d81f233a6a4f853ddbd981a8784bc41

There's another piece that I added about awareness, to provide access to the awareness throughout the React component tree. I couldn't quite figure out how to wrap the awareness crdt in reactive/syncedstate (though I admit I haven't yet tried very hard 🙈 ) and ended up subscribing to awareness changes in a useEffect hook and mirroring them into React state that is provided by my context provider. This all happens in this part of this gist: https://gist.github.com/jasonm/8d81f233a6a4f853ddbd981a8784bc41#file-synccontext-tsx-L51-L74

However (back to my original caveat) this seems to rely on the provider being connected, which isn't great for an offline-friendly/offline-first approach. Perhaps I should not rely on storing the user identity state (currentUserId / JWT claims / etc) into the awareness crdt, and instead store it elsewhere (plain react state?) and then push the interesting parts into provider.awareness purely for, well, awareness (cursors, etc.)

@YousefED I wonder if you've thought about this?

YousefED commented 2 years ago

I'm keeping my reply focused on Awareness (if you want to discuss Redux we can do it in a different issue or on discuss.yjs.dev)

However (back to my original caveat) this seems to rely on the provider being connected

Afaik, Awareness in yjs is really only used to broadcast information to connected peers while they are online. It is not meant / suitable for "storing" data. So this works well for cursors, presence, mouse positions, etc.

User identity state should be handled separately, although you can use Awareness to broadcast the username / cursor of the user that is logged in.

I have not yet digged into whether it would be useful to directly expose Awareness via SyncedStore - but of course you can access it via the underlying Yjs structures. Hope this makes sense!