Skip to content
Technical Article2SVII Internal Work

Drift — a synchronisation engine for unreliable connectivity

A TypeScript library implementing per-field conflict resolution with vector clocks, extracted from the offline synchronisation research.

Author
Sidney Okine2SVII, co-founder
Published
Reading time
1 min

Release

BetaVersion 0.4.2

Install

npm install @2svii/drift
Licence
Apache-2.0
Environments
Node.js 20+Modern browsers (ES2022)React Native 0.74+Cloudflare Workers
Known limitations
  • List reordering is not resolved automatically and is surfaced to the caller as an explicit conflict.
  • Vector clock metadata grows linearly with the number of replicas that have ever written to a record. Above roughly 50 replicas per record, the storage overhead becomes significant.
  • No built-in transport. The engine produces and consumes sync payloads; delivery is the caller's responsibility.

Drift is the reusable extraction of the merge strategy evaluated in our offline synchronisation research. It resolves concurrent edits per field rather than per record, and it reports what it could not resolve instead of guessing.

Usage

import { createStore, merge } from "@2svii/drift";

const store = createStore({ deviceId: await getStableDeviceId() });

const result = merge(store.local(recordId), incomingRemote);

if (result.conflicts.length > 0) {
  // Drift never silently picks a winner for unorderable edits — the caller
  // decides whether to prompt, queue or apply a domain-specific rule.
  await presentConflicts(result.conflicts);
}

await store.commit(result.merged);
typescriptMerging a local and a remote copy of the same record.

What it deliberately does not do

  • No transport. Drift produces and consumes payloads; how they reach the server is your concern.
  • No storage engine. It reads and writes through an adapter interface you provide.
  • No automatic list reconciliation. Per-field resolution cannot express reordering, so Drift reports it rather than pretending otherwise.