Get auto-completion and in-code errors with end-to-end type-safety.
Build for either Cloudflare Workers or Node.js runtimes.
Edit shared data and documents with the Yjs ecosystem.
Display user selections with per-user presence states.
Add your own custom authentication rules to rooms.
Broadcast custom events to connected clients in the same room.
1import {2 useMyPresence,3 useOthers,4 useStorage,5} from "client/pluv";6import type { FC } from "react";78export const Room: FC = () => {9 // Get data and yjs shared type for mutations10 const [boxes, sharedType] = useStorage("boxes");11 // { first: { x: -56, y: 0 },12 // second: { x: 56, y: 0 } }1314 // Observe and update your selection15 const [selection, setPresence] = useMyPresence((me) => me.selection);16 setPresence({ selection: "first" });1718 // Get selections of other users19 const selections = useOthers((others) => {20 return others.map((other) => other.presence.selection);21 });2223 // return ...24};
1// server/pluv.ts23import { createIO } from "@pluv/io";4import { platformCloudflare } from "@pluv/platform-cloudflare";5import { z } from "zod";67// Create your PluvIO server8const io = createIO({9 platform: platformCloudflare(),10})11 .event("EMIT_FIREWORK", {12 input: z.object({ color: z.string() }),13 resolver: ({ color }) => ({14 FIREWORK_EMITTED: { color },15 }),16 })17 .event("SEND_MESSAGE", {18 // Set input validator and type19 input: z.object({}),20 // Set output value and type21 resolver: ({}) => ({}),22 });
1// client/Room.tsx23import { useBroadcast, useEvent } from "client/pluv";4import { FC, useCallback, useState } from "react";56export const Room: FC = () => {7 const [messages, setMessages] = useState<string[]>([]);89 // Listen to new messages from the server10 // Get types from the SEND_MESSAGE resolver output11 useEvent("MESSAGE_RECEIVED", ({}) => {12 setMessages((prev) => [...prev]);13 });1415 const broadcast = useBroadcast();1617 const onSubmit = useCallback((message: string) => {18 // Broadcast to all users19 // Get types from the SEND_MESSAGE zod input20 broadcast("SEND_MESSAGE", {});21 }, [broadcast]);2223 // return ...24};