-
Notifications
You must be signed in to change notification settings - Fork 20
Description
Problem
When using vanilla valtio the way to initialize it is to add data when creating the proxy. While this is not shown in the valtio-yjs readme it is an easy mistake to make. The problem is that whatever data is added in the proxy is causing an update in the yjs doc every time the bind method is called. This leads to data corruption. The issue is that the normal proxy is also inferring the type from the provided data so just not providing data leads to having no types at all. Currently we are working around this by calling proxy like this:
const store = proxy({} as OurDataType)
While this is a lie the expectation is that the persisted data is coming from the yjs doc.
Solution
Valtio-yjs should abstract the proxy. Currently the adoption seems like a consumer would have both a store and a yjs doc available. However the yjs doc is the way the data is transmitted (through adapters), stored (locally or in db) and conflicts are handled. The store is only there as a consequence of the yjs doc and not as an equivalent. Treating it as such is confusing.
This would be a first idea about how the public interface could look like:
const yDoc = new Y.Doc()
const store = bind<OurDataType>(yDoc)Opportunity
While for an existing yjs doc the behavior should change like described above there is an opportunity here. Since the bind is inserting whatever it is provided this could be a great way to initialize a new yjs doc. Just providing a javascript type is preferable to the yjs canonical way of creating shared types and inserting them into each other manually. I would split this functionality to make its aim clear. It could look something like this:
const { store, yDoc, yMap } = createBoundStore({ property: "test", another_property: ["string"], .... })
const { store, yDoc, yArray } = createBoundStore(["string", "string2"])The returned yDoc does now contain the initialData and can be handled like it usually is.