Files
storage-v1/tests/document-db.test.ts

54 lines
2.2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
DocumentDB,
EventDB,
MemoryBlobStorage,
createDocumentEventIdentity,
type DocumentEvent,
} from "../src/index.js";
interface Note {
readonly _id: string;
readonly title: string;
}
async function createDatabases(options: { now?: () => number; nonce?: () => string; remoteRebuildDebounceMs?: number } = {}) {
const storage = new MemoryBlobStorage<DocumentEvent>();
const events = await EventDB.open(storage, { identify: createDocumentEventIdentity() });
const documents = await DocumentDB.open(events, options);
return { storage, events, documents };
}
describe("DocumentDB", () => {
it("provides read-your-writes for replacement, deletion, and recreation", async () => {
let nonce = 0;
const { documents } = await createDatabases({ now: () => 10, nonce: () => `nonce-${nonce++}` });
const notes = documents.collection<Note>("notes");
await notes.put({ _id: "one", title: "first" });
await notes.put({ _id: "one", title: "replacement" });
expect(notes.get("one")).toEqual({ _id: "one", title: "replacement" });
await notes.delete("one");
expect(notes.get("one")).toBeUndefined();
await notes.put({ _id: "one", title: "recreated" });
expect(notes.find((note) => note.title.startsWith("re"))).toEqual([{ _id: "one", title: "recreated" }]);
});
it("opens with historical state and rebuilds late events in deterministic order", async () => {
const storage = new MemoryBlobStorage<DocumentEvent>();
const events = await EventDB.open(storage, { identify: createDocumentEventIdentity() });
await events.append({
version: 1, timestamp: 20, nonce: "new", type: "document.put",
collection: "notes", documentId: "one", document: { _id: "one", title: "newer" },
});
const documents = await DocumentDB.open(events);
const notes = documents.collection<Note>("notes");
expect(notes.get("one")?.title).toBe("newer");
await events.append({
version: 1, timestamp: 10, nonce: "late", type: "document.delete",
collection: "notes", documentId: "one",
});
await documents.rebuild();
expect(notes.get("one")?.title).toBe("newer");
});
});