API Reference
createIO
Returns a PluvIO
instance.
Creates a server-side PluvIO
client that can be used to create event procedures, routers and servers. Below will show an example configuration for createIO
. To learn more about createIO
, read Authorization, Cloudflare Workers, Node.js and PubSub.
import { yjs } from "@pluv/crdt-yjs";
import { createIO } from "@pluv/io";
import { platformNode } from "@pluv/platform-node";
import { z } from "zod";
import { Database } from "./db";
const io = createIO({
// Optional: if provided, defines authorization for rooms created by io
authorize: {
// If required is false, users can authenticate for a room to
// attach an identity to their presence. Otherwise they will be
// anonymous.
required: true,
// The secret for generating your JWT
secret: process.env.PLUV_AUTH_SECRET!,
// The shape of your user object. `id` must always be required.
user: z.object({
id: z.string(),
// Here is an additional field we wish to add.
name: z.string(),
}),
},
// Optional: if provided, this context will be made available in event
// handlers and procedures
context: () => ({
db: new Database(process.env.DATABASE_URL),
}),
// Optional. Specify to use Yjs CRDT for storage.
// This is required only if/when you wish to use storage features.
crdt: yjs,
// Enable @pluv/io for Node.js
platform: platformNode(),
});
PluvIO
This is the client returned by createIO
.
createToken
Returns Promise<string>
.
Creates a JWT for a user trying to connect to a room. This should be called within a custom authentication endpoint you define. See Authorization for more information.
const token = await io.createToken({
// If using @platform/node
req: req as IncomingMessage,
// If using @platform/cloudflare
// This is the env from the Cloudflare worker handler's fetch function
env: env as Env,
request: request as Request,
// ...
room: "my-example-room",
user: {
id: "abc123",
name: "leedavidcs",
},
});
procedure
Creates a new type-safe event procedure to be broadcasted from PluvClient
. See Define Events for more information.
import { createIO } from "@pluv/io";
import { platformNode } from "@pluv/platform-node";
import { z } from "zod";
const io = createIO({ platform: platformNode() });
const sendMessage = io.procedure
.input(z.object({ message: z.string() }))
.broadcast(({ message }) => ({ receiveMessage: { message } }));
const doubleValue = io.procedure
.input(z.object({ value: z.number() }))
.broadcast(({ value }) => ({ receiveValue: { value: value * 2 } }));
const wave = io.procedure
.broadcast(() => ({ receiveMessage: { message: "Hello world!" } }));
router
Creates a new type-safe event procedure router to attach events and connect to a PluvServer
.
import { createIO } from "@pluv/io";
import { platformNode } from "@pluv/platform-node";
import { z } from "zod";
const io = createIO({ platform: platformNode() });
const sendMessage = io.procedure
.input(z.object({ message: z.string() }))
.broadcast(({ message }) => ({ receiveMessage: { message } }));
const doubleValue = io.procedure
.input(z.object({ value: z.number() }))
.broadcast(({ value }) => ({ receiveValue: { value: value * 2 } }));
const wave = io.procedure
.broadcast(() => ({ receiveMessage: { message: "Hello world!" } }));
const router = io.router({
sendMessage,
doubleValue,
wave,
});
server
Creates a PluvServer
that will create rooms to register your websockets to.
import { createIO } from "@pluv/io";
import { platformNode } from "@pluv/platform-node";
import { z } from "zod";
const io = createIO({ platform: platformNode() });
const router = io.router({ /* ... */ });
const server = io.server({
// Optional. Only needed to load persisted storage for rooms.
// Load storage for a newly created room.
getInitialStorage: async ({ room }) => {
const existingRoom = await db.room.findUnique({ where: { room } });
return existingRoom?.encodedState ?? null;
},
// Optional. Only needed for persisting storage for rooms.
// Before the room is destroyed, persist the state to a database to load
// when the room is re-created.
onRoomDeleted: async ({ encodedState, room }) => {
await db.room.upsert({
where: { room },
create: { encodedState, room },
update: { encodedState },
});
},
// Optional. It is unnecessary to save the storage state in this listener.
// If a room already exists, users will load the currently active storage
// before the storage from initialStorage.
onStorageUpdated: ({ encodedState, room }) => {
console.log(room, encodedState);
},
// Optional. Only needed if specifying events
router,
});
// Can also be created without a router, if events are unneeded
const server = io.server();
PluvServer
createRoom
Returns IORoom
.
Creates a room with the specified id.
const room = server.createRoom("my-example-room");
IORoom
This is the room returned by PluvServer.createRoom
. This is what websockets are registered to.
broadcast
Returns void
.
Broadcasts an event to all connected websockets to the room.
// The below 2 statements are equivalent
room.broadcast("sendMessage", { message: "Hello world~!" });
room.broadcast.sendMessage({ message: "Hello world~!" });
id
Type of string
.
This is the id of the room, when the room was created.
const roomId = room.id;
register
Returns Promise<void>
.
Registers a websocket to the room. Accepts a secondary options parameter to pass-in a token for authorizing the room. Read Cloudflare Workers, Node.js and Authorization to learn more.
// const token: string = ...
room.register(webSocket, { token });