Yjs Storage
pluv.io supports conflict-free replicated data-types (CRDT) storage with yjs. This allows modifying shared data between multiple users, and also leveraging some libraries within the yjs ecosystem such as rich-text-editor bindings.
Specify Yjs CRDT on PluvIO
To get started with yjs for pluv.io, first specify which CRDT you intend to use on your PluvIO
instance.
import { yjs } from "@pluv/crdt-yjs";
const io = createIO({
// ...
crdt: yjs,
});
Set initialStorage
Then set an initialStorage
config on your createClient
config.
import { yjs } from "@pluv/crdt-yjs";
import { createBundle, createClient } from "@pluv/react";
import type { AppPluvIO } from "backend/io";
const client = createClient({
infer: (i) => ({ io: i<AppPluvIO> }),
// Set the initial storage value, and type here
// Don't worry, we can set a different default value in the room component
initialStorage: yjs.doc(() => ({
messages: yjs.array(["hello world!"]),
})),
wsEndpoint: ({ room }) => `${process.env.WS_ENDPOINT}/api/room/${room}`,
});
export const pluv = createBundle(client);
Setup PluvRoomProvider
Then, setup PluvRoomProvider
with your new initialStorage
if it is different than your default set from createClient
.
import { yjs } from "@pluv/crdt-yjs";
import type { FC } from "react";
import { pluv } from "./frontend/io";
export const MyPage: FC = () => {
return (
<pluv.PluvRoomProvider
room="my-room-id"
initialStorage={() => ({
messages: yjs.array(),
})}
>
<MyRoom />
</pluv.PluvRoomProvider>
);
};
Use yjs shared-types
We can then use yjs shared-types to leverage shared CRDTs between connected clients using useStorage
.
import { pluv } from "frontend/io";
import { useCallback } from "react";
// "messages" is a key from the root properties of `initialStorage`.
const [messages, sharedType] = pluv.useStorage("messages");
const addMessage = useCallback((message: string) => {
sharedType?.push([message]);
});
messages?.map((message, i) => <div key={i}>{message}</div>)