Rebasely Beta: data may be purged

examples/live-notes Public

TypeScript · 49 lines · 2.3 KiB · at 70b1506

// The live-notes Worker. It routes each note to its own NoteRoom by name, so every editor of// "groceries" reaches the same object wherever they are.////   GET /notes/:id                       the note as JSON: { id, text, version }//   GET /notes/:id/ws                    upgrade to a WebSocket and edit the note (protocol.ts)//   GET /notes/:id/snapshots?after=n     the note's saved snapshots, oldest first (snapshots.ts)//   GET /notes/:id/snapshots/:version    the note's text at that version, as text/plain//// Snapshots are read straight from R2, so looking at a note's history never wakes its room.import type { NoteRoom } from "./note-room.ts";import { route } from "./routes.ts";import { listSnapshots, readSnapshot } from "./snapshots.ts";export { NoteRoom } from "./note-room.ts";export interface Env {  NOTES: DurableObjectNamespace<NoteRoom>;  SNAPSHOTS: R2Bucket;}export default {  async fetch(request, env): Promise<Response> {    const url = new URL(request.url);    const r = route(url.pathname);    if (!r) return new Response("not found", { status: 404 });    if (request.method !== "GET") return new Response("method not allowed", { status: 405, headers: { allow: "GET" } });    const objectId = env.NOTES.idFromName(r.id);    if (r.kind === "snapshots") {      const after = Number(url.searchParams.get("after") ?? 0);      if (!Number.isSafeInteger(after) || after < 0) return new Response("after is a version number", { status: 400 });      return Response.json({ id: r.id, ...(await listSnapshots(env.SNAPSHOTS, objectId.toString(), after)) });    }    if (r.kind === "snapshot") {      const text = await readSnapshot(env.SNAPSHOTS, objectId.toString(), r.version);      if (text === null) return new Response("no snapshot of that version", { status: 404 });      return new Response(text, { headers: { "content-type": "text/plain; charset=utf-8", "cache-control": "public, max-age=31536000, immutable" } });    }    const room = env.NOTES.get(objectId);    if (r.kind === "socket") {      if (request.headers.get("Upgrade") !== "websocket") return new Response("expected a WebSocket upgrade", { status: 426 });      return room.fetch(request);    }    const note = await room.read();    return Response.json({ id: r.id, text: note.text, version: note.version });  },} satisfies ExportedHandler<Env>;