Node.js

pluv.io supports building real-time APIs with Node.js. You can define your handler and websocket server manually if you need more control, but if you'd like to get started quicky, check out createPluvHandler.

Using with Node.js (manual)

Let's step through how we'd put together a real-time API for Node.js.

Install dependencies

1# For the server
2npm install @pluv/io @pluv/platform-node
3# Server peer-dependencies
4npm install ws zod
5# CRDT dependencies
6npm install @pluv/crdt-yjs yjs

Create PluvIO instance

Define an io (websocket client) instance on the server codebase:

1// backend/io.ts
2
3import { yjs } from "@pluv/crdt-yjs";
4import { createIO } from "@pluv/io";
5import { platformNode } from "@pluv/platform-node";
6
7export const io = createIO({
8 crdt: yjs,
9 platform: platformNode(),
10});
11
12// Export the websocket client io type, instead of the client itself
13export type AppPluvIO = typeof io;

Integrate PluvIO with ws

Integrate with ws on your Node.js server.

1// backend/server.ts
2
3import express from "express";
4import Http from "http";
5import WebSocket from "ws";
6import { io } from "./io";
7
8const PORT = 3000;
9
10const app = express();
11const server = Http.createServer();
12const wsServer = new WebSocket.Server({ server });
13
14const parseRoomId = (url: string): string => {
15 /* get room from req.url */
16};
17
18wsServer.on("connection", async (ws, req) => {
19 const roomId = parseRoomId(req.url);
20 const room = io.getRoom(roomId);
21
22 await room.register(ws);
23});
24
25server.listen(PORT, () => {
26 console.log(`Server is listening on port: ${port}`);
27});

createPluvHandler

If you don't need to modify your websocket server or handler too specifically, @pluv/platform-node also provides a function createPluvHandler to create a websocket server and handler for your automatically.

1import { yjs } from "@pluv/crdt-yjs";
2import { createIO } from "@pluv/io";
3import { createPluvHandler, platformNode } from "@pluv/platform-node";
4import bodyParser from "body-parser";
5import cors from "cors";
6import express from "express";
7import Http from "http";
8import WS from "ws";
9
10const io = createIO({
11 crdt: yjs,
12 platform: platformNode(),
13});
14
15const app = express();
16const server = Http.createServer(app);
17
18const Pluv = createPluvHandler({
19 // Your PluvIO instance
20 io,
21 // Optional: Specify the base path from which endpoints are defined
22 endpoint: "/api/pluv", // defaults to "/api/pluv"
23 // Your Http.Server instance
24 server,
25 // If your PluvIO instance defines authorization, add your authorization
26 // logic here. Return a user if authorized, return null or throw an error
27 // if not authorized.
28 async authorize({ req, res, roomId }) {
29 return {
30 id: "abc123",
31 name: "leedavidcs",
32 };
33 },
34});
35
36// Create your WS.Server instance, which listens to "connection" events
37const wsServer = Pluv.createWsServer();
38
39// Alternatively, define your own websocket server
40const wsServer = new WS.Server({ server });
41
42wsServer.on("connection", async (ws, req) => {
43 const { matched } = await Pluv.wsHandler(ws, req);
44
45 if (matched) return;
46
47 // didn't match with the Pluv handler, add your own logic
48 // ...
49});
50
51app.use(bodyParser.json());
52app.use(cors({ origin: "*" }));
53app.use(Pluv.handler);
54
55server.listen(3000);