Sync Engine
How Store replicates data across devices using a queue-based sync engine with pluggable conflict resolution.
Architecture
The sync engine sits between your local adapter and one or more remote targets. Every write operation produces an operation-log entry. Manual profiles flush that queue on demand; continuous profiles can be wired to background workers.
App → Store → Local Adapter → Sync Queue → Remote(s)
↑
Pull + Merge
Configuring sync
Sync is configured in the active profile through remote targets, routes, and sync policy.
import { createStore } from "@cuitty/store/client";
const store = await createStore({
module: "tasks",
profile: {
id: "team",
name: "Team",
local: { adapter: "local.sqlite", path: ".cuitty/store/tasks.sqlite" },
remotes: [{ id: "team-postgres", adapter: "postgres.record", dsnRef: "secret://pg" }],
routes: [{ namespace: "tasks", class: "record", localAdapter: "local.sqlite", remoteAdapters: ["team-postgres"] }],
encryption: { atRest: "preferred", remote: "required", p2p: "disabled" },
sync: { mode: "manual", flushEveryMs: 5000 },
},
schema: { tasks: { class: "record" } },
});
Conflict strategies
When two devices modify the same record before syncing, a conflict can occur. Current public client APIs expose the local operation log and sync controller; conflict policy is encoded by the sync service and profile route implementation.
Last-write-wins
The write with the most recent timestamp takes precedence. This is simple and suitable for most cases.
await store.record("tasks").put("task:1", { title: "Ship", updatedAt: Date.now() });
await store.sync.flush();
Custom merge function
Custom merge belongs in the application or sync service. Model the merged record explicitly and write it back with an idempotency key.
await store.record("tasks").put("task:1", {
title: "Ship",
tags: ["client", "server"],
}, {
idempotencyKey: "merge:task:1",
});
Manual resolution
Manual resolution is represented as a normal write with application-selected content.
await store.record("tasks").put("task:1", selectedResolution, {
idempotencyKey: "resolve:task:1",
});
Sync queue and planner
The sync planner optimizes network usage by batching writes, deduplicating consecutive updates to the same key, and compressing payloads. If the same record is updated five times while offline, only the final state is transmitted during sync.
The queue persists to disk so pending operations survive process restarts.