Sovereign SQLite/OPFS storage primitive — implements storage:v1, task:v1, and session:v1 contracts backed by a CRDT op-log (ADR-028). Usable independently of the full Refarm stack.
- You need a local-first, offline-capable storage layer in the browser (OPFS) or Node.js.
- You are implementing a
task:v1orsession:v1adapter and want the reference SQLite implementation. - You are composing with
@refarm.dev/sync-loro: this package serves as the read model (SQL-queryable materialized view); Loro is the write model.
npm install @refarm.dev/storage-sqliteWrite path: LoroDoc (CRDT) → op-log table (triples) → Projector → nodes table
Read path: nodes table → StorageAdapter queries
The schema has two tables:
nodes— materialized view of current state (fast reads)crdt_ops— append-only op-log using Hybrid Logical Clock timestamps (convergence guarantee)
See ADR-028 for the triple-based op-log design.
import { OPFSSQLiteAdapter } from "@refarm.dev/storage-sqlite";
const adapter = new OPFSSQLiteAdapter("my-app");
await adapter.open(); // opens /opfs/refarm-my-app.db
await adapter.put({ id: "note-1", type: "note", payload: "{}", createdAt: "...", updatedAt: "..." });
const note = await adapter.get("note-1");import { StorageSqliteV1Provider } from "@refarm.dev/storage-sqlite";
const provider = new StorageSqliteV1Provider(); // falls back to :memory:
await provider.open();import { createTaskV1StorageAdapter } from "@refarm.dev/storage-sqlite";
const adapter = createTaskV1StorageAdapter(sqliteDb);
const task = await adapter.create({ "@type": "Task", title: "...", status: "pending", ... });import { createSessionV1StorageAdapter } from "@refarm.dev/storage-sqlite";
const adapter = createSessionV1StorageAdapter(sqliteDb);import { runMigrations, PHYSICAL_SCHEMA_V1 } from "@refarm.dev/storage-sqlite";
await runMigrations(db); // idempotent — safe to call on every startupimport { runStorageV1Conformance } from "@refarm.dev/storage-contract-v1";
import { runTaskV1Conformance } from "@refarm.dev/task-contract-v1";
import { runSessionV1Conformance } from "@refarm.dev/session-contract-v1";
import { StorageSqliteV1Provider, createTaskV1StorageAdapter, createSessionV1StorageAdapter } from "@refarm.dev/storage-sqlite";
const result = await runStorageV1Conformance(new StorageSqliteV1Provider());
expect(result.pass).toBe(true);- ADR-009 — OPFS persistence strategy
- ADR-015 — SQLite engine choice
- ADR-028 — CRDT-SQLite CQRS convergence
MIT