Loading Storage
Listen to when a room is deleted so that when the same room is re-created, users can resume from the same storage as where they left off.
Add listeners
Every time a room is freshly created, the getInitialStorage
listener will run, and the return value of this function will set the initial value of the room's storage.
Beyond this, the IOServer
provides several event listeners in which you can hook into and save the room's current storage state. It is recommended that you do not save your room's storage state in a handler that runs too frequently so that your database isn't overly written to.
Our recommendation is to save your room's storage state in onRoomDeleted
. And if you need more saves beyond that, to throttle writes per room in event listeners such as onStorageUpdated
or onRoomMessage
.
// server/io.ts
import { yjs } from "@pluv/crdt-yjs";
import { createIO } from "@pluv/io";
import { platformNode } from "@pluv/platform-node";
import { db } from "./db";
export const io = createIO(
platformNode({
// Specify which CRDT to use here
crdt: yjs,
})
);
export const ioServer = io.server({
// Optional: Triggered when a room is freshly created. If the room existed
// before, you can load the storage state for the room by returning it here
getInitialStorage: async ({ context, room }) => {
const { db } = context;
const existingRoom = await db.room.findUnique({ where: { room } });
return existingRoom?.encodedState ?? null;
},
// Optional: Triggered when a room is deleted. Callback includes the last
// value for the room's state for persisting purposes
onRoomDeleted: async ({ context, encodedState, room }) => {
const { db } = context;
await db.room.upsert({
where: { room },
create: { encodedState, room },
update: { encodedState },
});
},
// Optional: Triggered each time any participant sends a new message to
// other participants
// It is advised not to perform any heavy operations in this listener
// due to the frequency of invocations
onRoomMessage: async ({ context, encodedState, room }) => {
// ...
},
// Optional: Triggered each time the room's storage is updated.
// It is advised not to perform any heavy operations in this listener
// due to the frequency of invocations
onStorageUpdated: ({ context, encodedState, room }) => {
// ...
},
// Optional: Triggered each time a user connects to a room
onUserConnected: ({ context, encodedState, room, user }) => {
// ...
},
// Optional: Triggered each time a user disconnects from a room
onUserDisconnected: ({ context, encodedState, room, user }) => {
// ...
},
});