🔒
Type-Safe
Full TypeScript support with automatic type inference from shared definitions
End-to-end type safety for real-time applications
npm install @wrpc/core @wrpc/server @wrpc/clientimport { defineWrpc, defineWrpcRoom } from "@wrpc/core";
import { z } from "zod";
const chat = defineWrpcRoom({
state: z.object({
messages: z.array(z.string()),
}),
initialState: {
messages: [],
},
broadcasts: {
message: {
input: z.object({
text: z.string(),
}),
},
},
events: {
sendMessage: {
input: z.object({
text: z.string(),
}),
},
},
});
export const wrpc = defineWrpc({
rooms: { chat },
});import { createWrpcServer } from "@wrpc/server";
import { wrpc } from "./wrpc";
const wrpcServer = createWrpcServer(wrpc);
const chat = wrpcServer.rooms.chat({
events: {
sendMessage: ({ state, input, broadcast }) => {
state.messages.push(input.text);
broadcast("message", { text: input.text });
},
},
});
const handler = wrpcServer.handler({
rooms: { chat },
});import { createWrpcClient } from "@wrpc/client";
import { wrpc } from "./wrpc";
const client = createWrpcClient(wrpc, {
url: "ws://localhost:3000/wrpc",
});
const room = await client.rooms.chat.join("room-1");
room.on("message", ({ text }) => {
console.log("New message:", text);
});
room.sendEvent("sendMessage", { text: "Hello!" });Extend rooms to inherit behaviors and add new functionality:
const baseRoom = defineWrpcRoom({
state: z.object({ count: z.number() }),
initialState: { count: 0 },
});
const extendedRoom = baseRoom.extend(() => ({
events: {
increment: {
input: z.object({}),
},
},
}));Create hierarchical room structures:
const card = defineWrpcRoom({
abstract: true,
});
const game = defineWrpcRoom({
rooms: { card },
});Organize connections within rooms:
const room = wrpcServer.rooms.game({
onJoin: ({ client, groups }) => {
groups.addToGroup(client.id, "team-red");
},
events: {
attack: ({ broadcast, groups }) => {
const targets = groups.getGroupMembers("team-blue");
broadcast("attacked", {}, { include: Array.from(targets) });
},
},
});MIT