Some updates on my progresses.
I am designing an architectural update of the repository, because it became just impossible to use in practice.
What I have in mind is designing a monolithic zustand store to keep references of all the Y.Doc of the app. This way I can expose some functions to handle array creation and data binding.
Here the API I have in mind:
import {configureConnection, useArray} from 'zustand-yjs';
/**
* Called when a Y.Doc is created (the name of the doc is unknown in the store).
*
**/
configureConnection((yDocName, yDoc, previousYDocs, registerProvider, disconnect) => {
// Connect yDoc to some provider.
const provider = new WebrtcProvider(yDocName, ydoc)
registerProvider(yDocName, () => provider.disconnect());
// You might want to disconnect others
previousYDocs.forEach(([name, previousYDoc]) => {
disconnect(name);
});
});
const MyComponent =() => {
/*
Data is updated through Y.Array#observe, and is served by the hook
as transient data. @see https://github.com/pmndrs/zustand#transient-updates-for-often-occuring-state-changes
*/
const {data, push} = useArray<{foo: string}>('Root', 'MyArray');
const newFoo = () => push([{foo: "bar"}]);
return <div onClick={newFoo}>
{data.map(({foo}, index) => <span key={index}>{foo}</span>)}
</div>
}
The internal structures would look like:
/**
* {
* yDocs: {"Root": <a Y.Doc>},
* observers: {"Root": {"MyArray": [<Y.Array observer>]}},
* data: {"Root": {"MyArray": [{"foo": "bar"}]}},
* }
*/
I have some concerns regarding this architecture:
- We
observe
Y.AbstractType and never unObserve
it. Not sure about performance issue, nor a possible resolution.
- During observe, we actually store Y.Array#toArray or Y.Map#toJSON value in memory. I guess it would be possible to store in Zustand store only a kind of trigger like a
refresh: 0|1
and serve data
as a proxy to the Y.Array#toArray
– this way we don’t store data twice, and rely on y-js performance.