@ahmetskilinc/sync-client
v0.4.0
Published
Local-first client for sync-engine: optimistic transactions, offline queue, rebase, IndexedDB persistence
Maintainers
Readme
@ahmetskilinc/sync-client
The client half of sync-engine: a full local copy of your data, optimistic transactions, a durable offline queue, and automatic rebase of pending writes on top of incoming server state.
Every read is a synchronous local read — no loading states.
npm install @ahmetskilinc/sync-client @ahmetskilinc/sync-coreimport {
SyncClient,
WebSocketTransport,
IndexedDBPersistence,
} from "@ahmetskilinc/sync-client";
import { schema, Issue } from "./schema.js";
const client = new SyncClient({
schema,
transport: new WebSocketTransport("wss://sync.example.com"),
persistence: new IndexedDBPersistence(), // MemoryPersistence by default
onTransactionRejected: (id, reason) => console.warn(reason),
});
await client.start();
// Synchronous local reads.
const issues = client.store.getAll(Issue);
// Optimistic writes — applied locally, queued durably, sent as a delta.
client.update(Issue, issueId, { status: "done" });
// Several mutations, applied atomically by the server.
client.transact((tx) => {
tx.create(Issue, { title: "New", status: "todo", teamId });
tx.update(Issue, otherId, { status: "done" });
});Behaviour worth knowing
- Writes are optimistic. They apply locally at once, persist, and flush when online.
client.hasPendingChangestells you whether anything is unconfirmed. - Rejected transactions roll back automatically and call
onTransactionRejected. Surface that to the user — the local change disappears otherwise. - Conflicts resolve per property. Two people editing different fields of one record both win.
- Reconnects catch up incrementally, or re-bootstrap if the client is too far behind the server's sync log. Backoff is exponential with jitter.
stop()disconnects;start()resumes. Persisted state (snapshot, queue, sync ID) survives a reload.
Environment
ESM only. The package is safe to import in a server environment, but start() needs a WebSocket, and IndexedDBPersistence needs a browser — use MemoryPersistence elsewhere. Zero runtime dependencies beyond @ahmetskilinc/sync-core.
Full documentation: github.com/ahmetskilinc/sync-engine · Upgrading? See MIGRATION.md
MIT
