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

Presence

Presence is a per-connection state that allows users to track what other users are doing in the same room. Presence can be used to represent movement, selections, and characteristics of a user, and can be really important to building collaborative experiences.

Set presence

To get started with presence for pluv.io, first set a presence config on your createClient config.

import { createBundle, createClient } from "@pluv/react";
import type { AppPluvIO } from "backend/io";
import { z } from "zod";

const client = createClient({
    infer: (i) => ({ io: i<AppPluvIO> }),
    // Optional: Define the validation schema for presence, using zod
    presence: z.object({
        selectionId: z.string().nullable(),
    }),
    wsEndpoint: ({ room }) => `${process.env.WS_ENDPOINT}/api/room/${room}`,
});

export const pluv = createBundle(client);

Set initialPresence on PluvRoomProvider

import type { FC } from "react";
import { pluv } from "./frontend/io";

const Room: FC = () => {
    return (
        <pluv.PluvRoomProvider
            // Specify the initial presence for each newly connected user
            initialPresence={{
                selectionId: null,
            }}
            room="my-example-room"
        >
            <ChatRoom />
        </pluv.PluvRoomProvider>
    );
};

Observing presence

Current user's presence

import { useCallback } from "react";
import { pluv } from "./frontend/io";

const [myPresence, updateMyPresence] = pluv.useMyPresence();
//     ^? const myPresence: { selectionId: string | null } | null

const myself = pluv.useMyself();
//    ^? const myself: {
//        connectionId: string;
//        presence: { selectionId: string | null };
//        user: null;
//    } | null;

// Updating the current user's presence
const selectInput = useCallback((selectionId: string) => {
    updateMyPresence(selectionId);
}, [updateMyPresence]);

Others' presence

import { pluv } from "./frontend/io";

const others = pluv.useOthers();
//    ^? const others: readonly {
//        connectionId: string;
//        presence: { selectionId: string | null };
//        user: null;
//    } | null;

// const connectionId = others[0]?.connectionId!;

const other = pluv.useOther(connectionId);
//    ^? const other: {
//        connectionId: string;
//        presence: { selectionId: string | null };
//        user: null;
//    } | null;