Adapters
db-memory
In-memory adapter for testing
@rippledb/db-memory
A simple in-memory adapter for unit testing. No persistence, no dependencies.
Not for production. Data is lost when the process exits.
Installation
pnpm add @rippledb/db-memorynpm install @rippledb/db-memoryyarn add @rippledb/db-memoryUsage
import { MemoryDb } from "@rippledb/db-memory";
const db = new MemoryDb<MySchema>();
// Append changes
await db.append({
stream: "test-stream",
changes: [
{
entity: "todos",
entityId: "todo-1",
kind: "upsert",
patch: { title: "Test" },
tags: { title: hlc() },
hlc: hlc(),
},
],
});
// Pull changes
const { changes, nextCursor } = await db.pull({
stream: "test-stream",
cursor: null,
});Features
- Zero config: No database setup required
- Fast: Pure JavaScript, no I/O
- Isolated: Each instance has its own state
- Full Db interface: Supports
append,pull, idempotency
Limitations
- No materialization: Only stores the change log
- No persistence: Data lives only in memory
- Single process: Can't share state between processes
Testing Example
import { describe, it, expect, beforeEach } from "vitest";
import { MemoryDb } from "@rippledb/db-memory";
import { makeUpsert } from "@rippledb/core";
describe("TodoService", () => {
let db: MemoryDb<MySchema>;
beforeEach(() => {
db = new MemoryDb();
});
it("creates a todo", async () => {
await db.append({
stream: "user-123",
changes: [
makeUpsert({
stream: "user-123",
entity: "todos",
entityId: "todo-1",
patch: { id: "todo-1", title: "Test", done: false },
hlc: "1000:0:test",
}),
],
});
const { changes } = await db.pull({ stream: "user-123", cursor: null });
expect(changes).toHaveLength(1);
expect(changes[0].patch.title).toBe("Test");
});
it("supports idempotency", async () => {
const change = makeUpsert({
stream: "user-123",
entity: "todos",
entityId: "todo-1",
patch: { id: "todo-1", title: "Test", done: false },
hlc: "1000:0:test",
});
// First append succeeds
const result1 = await db.append({
stream: "user-123",
changes: [change],
idempotencyKey: "key-1",
});
expect(result1.accepted).toBe(1);
// Second append with same key is ignored
const result2 = await db.append({
stream: "user-123",
changes: [change],
idempotencyKey: "key-1",
});
expect(result2.accepted).toBe(0);
});
});When to Use
| Scenario | Recommendation |
|---|---|
| Unit tests | db-memory |
| Integration tests | db-sqlite with :memory: |
| E2E tests | Real database adapter |
| Development | db-sqlite or db-turso |
Related
- db-sqlite — For tests needing materialization
- Server Reference — Full Db interface