import { assert, assertEquals } from "@std/assert"; import { applyImmutable, type Op } from "@earendil-works/chord/delta"; import { published, servePubsub, type ServerMessage } from "./pubsub.ts"; Deno.test("a history's snapshot brings its newest entries first, then the older ones before any ops", async () => { const sent: ServerMessage[] = []; let receive = (_: { data: string }) => {}; const socket = { readyState: WebSocket.OPEN, send: (frame: string) => sent.push(JSON.parse(frame)), addEventListener(type: string, listener: (event: { data: string }) => void) { if (type === "message") receive = listener; }, close() {}, } as unknown as WebSocket; const entry = (id: number) => ({ id, text: `${id} `.repeat(1000) }); const history = published({ docs: {}, entries: Array.from({ length: 200 }, (_, i) => entry(i)) }); servePubsub(socket, { authorize: () => true, resolve: () => Promise.resolve(history.feed()) }); receive({ data: JSON.stringify({ t: "auth", token: "token" }) }); receive({ data: JSON.stringify({ t: "sub", topic: "conversation:a" }) }); while (!sent.some((message) => message.t === "snapshot")) await Promise.resolve(); history.set({ ...history.value, entries: [...history.value.entries, entry(200)] }); const [ready, first, ...rest] = sent; assertEquals(ready, { t: "ready" }); assert(first.t === "snapshot" && first.older !== undefined); const tail = (first.value as typeof history.value).entries; assertEquals(tail.at(-1)!.id, 199); assertEquals(first.older + tail.length, 200); const older = rest.slice(0, -1); assert(older.length > 1 && older.every((message) => message.t === "older")); assertEquals(rest.at(-1)!.t, "ops"); let value = first.value as typeof history.value; for (const message of rest) { if (message.t === "older") { // newest first: each chunk ends just before what came already assertEquals((message.entries.at(-1) as { id: number }).id, value.entries[0].id - 1); value = { ...value, entries: [...message.entries as typeof tail, ...value.entries] }; } else if (message.t === "ops") value = applyImmutable(value, message.ops as Op[]); } assertEquals(value, history.value); });