Closed armincerf closed 2 years ago
Hi @armincerf!
While you can't replace an array / object on the root of the store, you can take one of the following approaches:
A) Replace array elements using splice
state.comments.splice(0, state.comments.length, data.comments);
B) Store array in a nested object
// first add an object "container" to the store shape, then:
state.container.comments = data.comments;
However, this (the answers above) is probably not what you want. Example of an issue you'd run into:
state.comments
with server side data on client A, this will be propagated to peers (assuming you use something like webrtc). Now, let's say client B just pushed a comment as well, but not yet to the server (e.g.: addCommentHook
is still in progress). Now, the new comment will disappear (or at least flash) as it's not yet in the latest data of the serverThe recommended way would be to persist the syncedstore / underlying yjs document to the database. You can do this using one of the https://syncedstore.org/docs/sync-providers, in particular y-websocket or hocuspocus would be relevant for your scenario (y-redis might also be interesting).
I agree that this is not yet trivial in the yjs ecosystem - most people write custom solutions now, but there's quite some development in this area at the moment as well. What kind of backend storage are you using / interested in?
Ok thank you that is good advice. I did try using splice but encountered a strange situation where my chat messages were duplicated. I was doing exactly what you suggested state.comments.splice(0, state.comments.length, data.comments);
Can try and put together a reproducible repo if you think that might be a bug.
I will look into using y-websocket but data from the server must be treated as a source of truth and I'm a bit worried about things not being in sync.. though I guess that's just part of the difficulty with this stuff. I don't think I can persist the yjs store directly because there are other clients connected to the backend API which need to read and modify the comments, but perhaps I can have my frontend only connect to the yjs backend, and have the yjs server sync with the main DB..
Anyway thanks again, feel free to close this
Alright, I'll close this for now. Splice should work, feel free to open a separate issue (ideally with codesandbox link) if you still run into issues.
If you need some more general pointers, feel free to comment in this thread. I'd need to know a little bit more of the system you envision (e.g.: what do you want to use SyncedStore for vs what scenarios should your backend support).
I don't think I can persist the yjs store directly because there are other clients connected to the backend API which need to read and modify the comments
Note that these two don't exclude each other. Your API could read the document and apply a change (modify / add / remove comments) to it.
ok here's a codesandbox that can reproduce some of my issues https://codesandbox.io/s/adoring-smoke-qzop9?file=/src/App.tsx
if you try opening it in two tabs and refreshing the first one, you'll see that 'foo' is duplicated. Also, I couldn't get the server data change test to work at all since I get Not supported: reassigning object that already occurs in the tree.
...
Not sure what's going on there since I thought you could reassign values with syncedstore, but I'm probably just not understanding how it works.. definitely feel out of my depth with this stuff haha
Thanks for providing the sandbox.
I've played around with it, and using a root array indeed has the issue that you don't know whether all data has been "loaded" when you delete the items using splice. So when you load the app, and call splice
the array might be empty, because it hasn't been loaded yet. splice
then doesn't delete all items (as length will be 0). As there's no eventually consistent operation to clear an array (e.g.: array.clear()
or .reset()
) operation this approach doesn't work.
The solution with a wrapper works better for your scenario, as you can just use a completely new array: https://codesandbox.io/s/elegant-faraday-l1jkk?file=/src/App.tsx
Hi, apologies if this question is answered elsewhere, I looked through all the docs and other issues and couldn't see anything though.
I have a simple chat app, and I would like to use this library to get instant updates. However, I also want each message to be persisted in my database, and when data is fetched from that db I want to replace the syncedstore with that new data.
So really I just want to do this:
However, this doesn't work because state.comments is read only. Is there a way to do this? Or am I going down the wrong path entirely?