Collaborative document
This example creates routes for a collaborative document surface. Clients send ordered updates, update awareness, read the document stream, and create snapshots.
Configure the app
Section titled “Configure the app”import { backend } from "@layeron/core"import { realtime } from "@layeron/modules"
const app = backend()const live = realtime({ name: "docs", historyLimit: 500,})app.use(live)Join the document
Section titled “Join the document”app.post("/documents/:documentId/join", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const documentId = pathSegments[2] return await live.crdtRoom(documentId).join({ presence: { status: "online", tool: "cursor", }, })})Apply document updates
Section titled “Apply document updates”app.post("/documents/:documentId/updates", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const documentId = pathSegments[2] const body = await request.json()
return await live.crdtRoom(documentId).applyUpdate({ update: body.update, clientId: body.clientId, clock: body.clock, })})Update awareness
Section titled “Update awareness”app.post("/documents/:documentId/awareness", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const documentId = pathSegments[2] const body = await request.json()
return await live.crdtRoom(documentId).awareness({ clientId: body.clientId, state: { cursor: body.cursor, selection: body.selection, color: body.color, displayName: body.displayName, }, })})Read the document stream
Section titled “Read the document stream”app.get("/documents/:documentId/state", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const documentId = pathSegments[2] const sinceClock = Number(new URL(request.url).searchParams.get("sinceClock") ?? 0)
return await live.crdtRoom(documentId).document({ sinceClock, limit: 200, })})Create a snapshot
Section titled “Create a snapshot”app.post("/documents/:documentId/snapshots", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const documentId = pathSegments[2] const snapshot = await live.crdtRoom(documentId).snapshot()
return Response.json(snapshot, { status: 201 })})Restore a snapshot
Section titled “Restore a snapshot”app.post("/documents/:documentId/restore", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const documentId = pathSegments[2] const body = await request.json()
return await live.crdtRoom(documentId).restore(body.snapshotId)})