API Reference
createClient
Returns a PluvClient
instance
Create a frontend PluvClient
that will create rooms to connect to your server's PluvIO
instance.
createClient basic example
If you've created a basic PluvIO
backend without any auth, you can create a PluvClient
with your websocket connection endpoint.
1// frontend/io.ts23import { createClient } from "@pluv/client";45const client = createClient({6 // Defaults to (room) => `/api/pluv/room/${room}`7 // This is the default from `createPluvHandler`.8 wsEndpoint: (room: string) => `/api/room?room=${room}`,9});
createClient with fetch options
If you need to use a POST request or specify additional headers, you can return an object containing options for fetch
.
1// frontend/io.ts23import { createClient } from "@pluv/client";45const client = createClient({6 wsEndpoint: (room: string) => ({7 url: "/api/room",8 // specify fetch options here9 options: {10 method: "post",11 body: JSON.stringify({ room }),12 },13 }),14});
createClient with auth endpoint
If your PluvIO
implements auth, you will need to specify an authEndpoint
on your frontend client.
1import { createClient } from "@pluv/client";23const client = createClient({4 wsEndpoint: (room: string) => `/api/room?room=${room}`,5 authEndpoint: (room: string) => `/api/room/auth?room=${room}`,6});
PluvClient
This is the client returned by createClient
.
PluvClient.createRoom
Returns a PluvRoom
instance
Create a PluvRoom
that websockets can join and leave. The second argument is an optional configuration for presence and storage. See the example below for the available properties of the configuration.
1// frontend/room.ts2import { yjs } from "@pluv/crdt-yjs";3import { z } from "zod";4import { client } from "./io.ts";56const room = client.createRoom("my-example-room", {7 /**8 * @description Define your presence schema9 */10 presence: z.object({11 selectionId: z.nullable(z.string()),12 }),13 /**14 * @description Define the user's initial presence15 */16 initialPresence: {17 selectionId: null,18 },19 /**20 * @description Define the initial storage for the room21 */22 initialStorage: yjs.doc(() => ({23 messages: yjs.array(["hello world!"]),24 })),25});
PluvClient.enter
Returns Promise<PluvRoom>
Establishes a websocket connection with a room. If the PluvClient
specifies an authEndpoint
, the endpoint will be called when this function is called. Returns the PluvRoom
that was entered.
Note: This method will fail if the room does not already exist beforehand.
1// frontend/room.ts2import { client } from "./io.ts";34const room = client.createRoom("my-example-room", {5 // ...6})78// Enter room by room name9client.enter("my-example-room").then(() => {10 console.log("Connected to: my-example-room");11});1213// Alternatively, you can pass the PluvRoom instance14client.enter(room).then(() => {15 console.log("Connected to: my-example-room");16});
PluvClient.getRoom
Returns a PluvRoom
instance or null
if none is found
1// frontend/room.ts23import { client } from "./io.ts";45const room = client.getRoom("my-example-room");
PluvClient.getRooms
Returns PluvRoom[]
Retrieves all active rooms under the current PluvClient
instance.
1// frontend/room.ts23import { client } from "./io.ts";45const rooms = client.getRooms();
PluvClient.leave
Returns void
Disconnects from a PluvRoom
and deletes the room on the PluvClient
. If the room does not exist, nothing happens and the function returns immediately.
1// frontend/room.ts23import { client } from "./io.ts";45const room = client.createRoom("my-example-room", {6 // ...7})89// Leave room by room name10client.leave("my-example-room");1112// Alternatively, you can pass the PluvRoom instance13client.leave(room);
PluvRoom
This is the room returned by PluvClient.createRoom
.
PluvRoom.webSocket
Type of WebSocket | null
This is the WebSocket that is created and attached to the room when connected to.
PluvRoom.broadcast
Returns void
Broadcasts an event to all websockets connected to the room.
1// frontend/room.ts23room.broadcast("EMIT_EMOJI", { emojiCode: 123 });
PluvRoom.canRedo
Returns boolean
Checks whether calling PluvRoom.redo will mutate storage.
1// frontend/room.ts23const canRedo: boolean = room.canRedo();
PluvRoom.canUndo
Returns boolean
Checks whether calling PluvRoom.undo will mutate storage.
1// frontend/room.ts23const canUndo: boolean = room.canUndo();
PluvRoom.connect
Returns Promise<void>
Connects to the room if not connected to already. If an authEndpoint
is configured, this function will call your authEndpoint
.
1// frontend/room.ts23room.connect().then(() => {4 console.log(`Connected to room: ${room.id}`);5});
PluvRoom.disconnect
Returns void
Disconnects from the room if already connected.
PluvRoom.event
Returns () => void
Subscribes to an event. These events are defined by PluvIO.event
and are emitted when other websockets emit events via PluvRoom.broadcast
.
1// Subscribe to EMOJI_RECEIVED messages2const unsubscribe = room.event("EMOJI_RECEIVED", ({ data }) => {3 console.log(data);4});56// ...78// Unsubscribe to the listener later on.9unsubscribe();
PluvRoom.getConnection
Returns WebSocketConnection
This returns state information for the current connection to this room.
1const connection = room.getConnection();
PluvRoom.getDoc
Returns AbstractCrdtDoc
from @pluv/crdt
This returns an instance of the AbstractCrdtDoc
that holds the underlying CRDT doc. For instance, when using @pluv/crdt-yjs
, this will hold a yjs in its value
property.
1import { yjs } from "@pluv/crdt-yjs";2import { Doc as YDoc } from "yjs";34const doc: yjs.CrdtYjsDoc<any> = room.getDoc();5const ydoc: YDoc = doc.value;
PluvRoom.getMyPresence
Returns TPresence | null
Returns the user's current presence data.
1const myPresence = room.getMyPresence();
PluvRoom.getMyself
Returns UserInfo | null
Returns a user info object containing data used when generating the JWT during authentication (see Authorization), the user's presence, and the user's connection id.
1const myself = room.getMyself();
PluvRoom.getOther
Returns UserInfo | null
Returns a user info object for the given connectionId
.
1// const connectionId = "some connection id of another connection"23const other = room.getOther(connectionId);
PluvRoom.getOthers
Returns UserInfo[]
Returns all user info objects for connections that are not the current user's.
1const others = room.getOthers();
PluvRoom.getStorage
Returns a CrdtAbstractType
from @pluv/crdt
that holds a CRDT shared type. For instance, if using @pluv/crdt-yjs
, the CrdtAbstractType
will hold a yjs shared type in its value
property.
1// frontend/room.ts2import { yjs } from "@pluv/crdt-yjs";3import { Array as YArray } from "yjs";4import { z } from "zod";5import { client } from "./io.ts";67const room = client.createRoom("my-example-room", {8 // Define your presence schema9 presence: z.object({10 selectionId: z.nullable(z.string()),11 }),12 // Define the user's initial presence13 initialPresence: {14 selectionId: null,15 },16 // Define the initial storage for the room17 initialStorage: yjs.doc(() => ({18 messages: yjs.array(["hello world!"]),19 })),20});2122// Get messages as defined from the `createRoom` config23const messages: yjs.CrdtYjsArray<string> = room.getStorage("messages");24// Get the underlying CRDT shared type via the value property25const sharedType: YArray<string> = messages.value;
PluvRoom.other
Returns () => void
Subscribes to a given user info object for a connection that isn't the current user's.
1// const connectionId = "some connection id of another connection"23const unsubscribe = room.other(connectionId, ({4 connectionId,5 presence,6 user7}) => {8 console.log(connectionId, presence, user);9});1011// ...1213// Unsubscribe to the listener later on.14unsubscribe();
PluvRoom.redo
Returns void
Re-applies the last mutation that was undone via PluvRoom.undo.
1// frontend/room.ts23room.redo();
PluvRoom.storage
Returns () => void
Subscribes to a given root-level value in the room's document storage. The data in the callback will be a serialized value rather than the CRDT's instance.
1// frontend/room.ts2import { yjs } from "@pluv/crdt-yjs";3import { z } from "zod";4import { client } from "./io.ts";56const room = client.createRoom("my-example-room", {7 // Define your presence schema8 presence: z.object({9 selectionId: z.nullable(z.string()),10 }),11 // Define the user's initial presence12 initialPresence: {13 selectionId: null,14 },15 // Define the initial storage for the room16 initialStorage: yjs.doc(() => ({17 messages: yjs.array(["hello world!"]),18 })),19});2021const unsubscribe = room.storage("messages", (messages: string[]) => {22 console.log(messages);2324 // If the AbstractCrdtType is needed, you call call getStorage here.25 const sharedType = room.getStorage("messages");26});2728// ...2930// Unsubscribe to the listener later on.31unsubscribe();
PluvRoom.subscribe("connection")
Returns () => void
Subscribes to the user's connection state.
1const unsubscribe = room.subscribe("connection", ({2 // The user's authorization state: { token, user }3 authorization,4 // The user's connection state: { id, state }5 connection,6 // The user's websocket7 webSocket,8}) => {9 console.log(authorization, connection, webSocket);10});1112// ...1314// Unsubscribe to the listener later on.15unsubscribe();
PluvRoom.subscribe("my-presence")
Returns () => void
Subscribes to the user's presence state.
1const unsubscribe = room.subscribe("my-presence", (myPresence) => {2 console.log(myPresence);3});45// ...67// Unsubscribe to the listener later on.8unsubscribe();
PluvRoom.subscribe("myself")
Returns () => void
Subscribes to the user's info object.
1const unsubscribe = room.subscribe("myself", (myself) => {2 console.log(myself);3});45// ...67// Unsubscribe to the listener later on.8unsubscribe();
PluvRoom.subscribe("others")
Returns () => void
Subscribes to the list of user info objects of the other connections that aren't the user's.
1const unsubscribe = room.subscribe("others", (others) => {2 console.log(others);3});45// ...67// Unsubscribe to the listener later on.8unsubscribe();
PluvRoom.transact
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.
1// frontend/transact23room.transact((tx) => {4 room.get("messages").push(["hello world!"]);56 // Alternatively, access your storage from here7 tx.messages.push(["hello world!"]);8});910// This will also be undoable if `"user-123"` is a tracked origin.11room.transact(() => {12 room.get("messages").push(["hello world!"]);13}, "user-123");
PluvRoom.undo
Returns void
Undoes the last mutation that was applied via PluvRoom.transact.
1// frontend/room.ts23room.undo();