pluv.io is in preview! Please wait for a v1.0.0 stable release before using this in production.

API Reference

createClient

Returns a PluvClient instance

This is a re-export of createClient from @pluv/client.

createBundle

Returns a CreateBundle instance

Creates a bundle to be able to access the PluvClient from a react hook.

CreateBundle

This is the bundle returned from createBundle.

createRoomBundle

Returns a CreateRoomBundle instance

Creates a bundle to be able to access PluvRoom capabilities from various react hooks.

1import { yjs } from "@pluv/crdt-yjs";
2
3// Destructured room bundle
4export const {
5 // components
6 PluvRoomProvider,
7
8 // hooks
9 useBroadcast,
10 useCanRedo,
11 useCanUndo,
12 useConnection,
13 useDoc,
14 useEvent,
15 useMyPresence,
16 useMyself,
17 useOther,
18 useOthers,
19 useRedo,
20 useRoom,
21 useStorage,
22 useTransact,
23 useUndo,
24} = createRoomBundle({
25 /**
26 * @optional
27 * @description Define the initial storage for the room, as well as the CRDT to use
28 */
29 initialStorage: yjs.doc(() => ({
30 messages: yjs.array([
31 yjs.object({
32 message: "hello",
33 name: "leedavidcs",
34 }),
35 ]),
36 })),
37 /**
38 * @optional
39 * @description Define your presence schema
40 */
41 presence: z.object({
42 count: z.number(),
43 }),
44});

PluvProvider

React provider component to allow the PluvClient created by createClient to be accessible in child components via useClient. This is identical to importing the created client, so this is primarily useful for dependency injection when testing.

1<PluvProvider>{children}</PluvProvider>

useClient

Returns PluvClient

Returns the PluvClient that was created via createClient.

CreateRoomBundle

This is the bundle returned from createRoomBundle.

MockedRoomProvider

React provider component to mock PluvRoomProvider. Enables hooks from CreateRoomBundle while completely offline. This can be useful in Storybook within a storybook decorator when mocking PluvRoomProvider.

1import { yjs } from "@pluv/crdt-yjs";
2import { MockedRoomProvider } from "./io";
3
4const MyComponent: FC = () => {
5 return (
6 <MockedRoomProvider
7 /**
8 * @description Mock events sent and received for hooks in child components.
9 */
10 //
11 events={{
12 EMIT_EMOJI: ({ emojiCode }) => ({
13 EMOJI_RECEIVED: { emojiCode },
14 }),
15 }}
16 /**
17 * @optional
18 * @description Define your initial presence
19 */
20 initialPresence={{
21 selectionId: null,
22 }}
23 /**
24 * @optional
25 * @description Define the initial storage for the room, as well as the CRDT to use
26 */
27 initialStorage={() => ({
28 messages: yjs.array(),
29 })}
30 /**
31 * @required
32 * @description Set the room id
33 */
34 room="my-mock-room"
35 >
36 {children}
37 </MockedRoomProvider>
38 );
39};

PluvRoomProvider

React provider component to enable CreateRoomBundle hooks within child components. Mounting this component connects to a real-time room with other connected users. Unmounting this component will disconnect the room. See Create Rooms for more details.

1import { yjs } from "@pluv/crdt-yjs";
2import { MockedRoomProvider } from "./io";
3
4const MyComponent: FC = () => {
5 return (
6 <PluvRoomProvider
7 /**
8 * @optional
9 * @description Define the user's initial presence
10 */
11 initialPresence={{
12 selectionId: null,
13 }}
14 /**
15 * @optional
16 * @description Define the initial storage for the room
17 */
18 initialStorage={() => ({
19 messages: yjs.array(),
20 })}
21 /**
22 * @optional
23 * @description Emits an error whenever authorization fails, for
24 * monitoring or debugging purposes
25 */
26 onAuthorizationFail={(error: Error) => {
27 console.error(error);
28 }}
29 /**
30 * @required
31 * @description Set the room id
32 */
33 room="my-room-id"
34 >
35 {children}
36 </PluvRoomProvider>
37 );
38};

useBroadcast

Returns (event, data) => void

Returns a broadcast function to emit an event and data to all connected clients. This is type-safe. The first parameter event will be the name of the event specified when creating your backend PluvIO instance and the second parameter data will be the associated response type. See Define Events for more details.

1const broadcast = useBroadcast();
2
3broadcast("EMIT_RECEIVED", { emojiCode: 123 });

useCanRedo

Returns boolean

Checks whether calling PluvRoom.redo will mutate storage.

1const canRedo: boolean = useCanRedo();

useCanUndo

Returns boolean

Checks whether calling PluvRoom.undo will mutate storage.

1const canUndo: boolean = useCanUndo();

useConnection

Returns WebSocketConnection

Returns the websocket connection start of the current user.

1const connection = useConnection();
2// ^? const connection: {
3// id: string | null;
4// state: ConnectionState;
5// }

useEvent

Returns void

Defines a listener for events broadcasted by connected clients. This is type-safe. The first parameter event is the name of the event to listen to from your backend PluvIO instance. The second parameter is a callback containing the data emitted from the broadcasted event.

1useEvent("EMOJI_RECEIVED", ({ emojiCode }) => {
2 console.log(emojiCode);
3});

useMyPresence

Returns [myPresence: TPresence | null, updatePresence: Function]

Returns the current user's presence, and a function to update the user's presence. Using this hook rerenders the component based on a deep-equality check on the user's presence value. This hook accepts a selector to return a modified presence to reduce rerenders.

1const { useMyPresence } = createRoomBundle({
2 // ...
3 presence: z.object({
4 selectionId: z.nullable(z.string()),
5 selectionColor: z.string(),
6 }),
7});
8
9const [
10 // the user's presence
11 myPresence,
12 // a presence updater function
13 updateMyPresence
14] = useMyPresence();
15
16// update individual base properties
17updateMyPresence({ selectionId: "name-input" });
18updateMyPresence({ selectionColor: "#123456" });
19
20// update multiple base properties
21updateMyPresence({
22 selectionId: "name-input",
23 selectionColor: "#123456",
24});
25
26// if you only need a partial presence
27const [myPresence] = useMyPresence(({ selectionId }) => selectionId);
28
29// if you don't need presence, and just want the updater
30const [, updateMyPresence] = useMyPresence(
31 // set selector to return a stable value
32 () => true
33);

useMyself

Returns UserInfo | null

Returns the user-info object for the current user. This hook accepts a selector to return a modified user-info to reduce rerenders.

1const myself = useMyself();
2
3// if you don't need the entire user-info
4const myself = useMyself(({ connectionId }) => connectionId);

useOther

Returns UserInfo | null

Returns the user-info object for a connected user by connectionId string.

1const other = useOther();
2
3// if you don't need the entire user-info
4const other = useOther(({ connectionId }) => connectionId);

useOthers

Returns readonly UserInfo[]

Returns all user-info objects for all connected users. This may trigger a lot of re-renders if presence updates frequently.

Note Consider using this hook only for deriving others' connectionId values to pass into useOther.

1const others = useOthers();
2
3// if you want to just pull out connectionId properties
4const connectionIds = useOthers((others) => {
5 return others.map(({ connectionId }) => connectionId);
6});

useRedo

Returns void

Re-applies the last mutation that was undone via PluvRoom.undo.

For more information see: History

1const redo = useRedo();
2
3redo();

useStorage

Returns [TData | null, AbstractCrdtType | null]

Returns a base-level property of our CRDT storage as a serialized value and a @pluv/crdt AbstractCrdtType that holds a shared type of our specified CRDT. The component is re-rendered whenever the AbstractCrdtType is updated. The returned values are null while the room is still connecting or initializing its storage.

1import { yjs } from "@pluv/crdt-yjs";
2
3const { useStorage } = createRoomBundle({
4 initialStorage: yjs.doc(() => ({
5 messages: yjs.array(["hello"]),
6 })),
7});
8
9const [messages, sharedType] = useStorage("messages");
10
11sharedType.push("world~!");
12
13messages.map((message, key) => <div key={key}>{message}</div>);

useTransact

Returns void

Performs a mutation that can be tracked as an operation to be undone/redone (undo/redo). When called without an origin, the origin will default to the user's connection id.

You can specify a 2nd parameter to transact with a different transaction origin.

For more information see: History

1const [messages, sharedType] = useStorage("messages");
2const transact = useTransact();
3
4transact((tx) => {
5 sharedType.push(["hello world!"]);
6
7 // Alternatively, access your storage from here
8 tx.messages.push(["hello world!"]);
9});
10
11// This will also be undoable if `"user-123"` is a tracked origin.
12transact(() => {
13 sharedType.push(["hello world!"]);
14}, "user-123");

useUndo

Returns void

Undoes the last mutation that was applied via PluvRoom.transact.

For more information see: History

1const undo = useUndo();
2
3undo();