The client maintains a state machine for connectivity:
- Disconnected (Offline): Operations are queued in OpLog.
- Connecting: Authenticating WebSocket handshake.
- Syncing (Push): Uploading local changes.
- Syncing (Pull): Downloading remote changes.
- Realtime (Online): Passive listening + immediate writes.
Stored in IndexedDB table oplog.
{
"id": 1001, // Auto-increment sequence
"key": "user:123",
"op": "PUT", // PUT, REMOVE
"val": "{\"name\":\"John\"}", // Serialized value
"hlc": "1678888.0.client1", // Timestamp
"synced": 0 // 0 = Pending, 1 = Acked
}Used for efficient state comparison.
- Bucket Count: Fixed (e.g., 256 buckets) or dynamic based on map size.
- Hashing: MurmurHash3 or xxHash of the serialized Record (Value + HLC).
- Leaf: Hash of all records in the bucket.
- Root: Hash of all bucket hashes.
Triggered upon connection established.
- Client:
SELECT * FROM oplog WHERE synced = 0 ORDER BY id ASC - Client: Batches operations and sends
OP_BATCHmessage.{ "type": "OP_BATCH", "ops": [ ... ] } - Server: Iterates ops.
- Compares
op.hlcwith Server's current record HLC. - If
op.hlc > server.hlc: Apply write. - If
op.hlc < server.hlc: Ignore write (outdated).
- Compares
- Server: Sends
OP_ACK { lastId: 1005 }. - Client:
UPDATE oplog SET synced = 1 WHERE id <= 1005.- Optimization: Delete synced rows immediately if no history is needed.
Triggered after Push Phase or periodically.
- Client: Calculates local Merkle Tree Root Hash.
- Client: Sends
SYNC_INIT { rootHash: "abc..." }. - Server: Compares with its own Root Hash.
- If Match: Sends
SYNC_COMPLETE. - If Mismatch: Requests Bucket Hashes.
- If Match: Sends
- Client: Sends
SYNC_BUCKETS { hashes: [...] }. - Server: Identifies mismatching buckets. Retrieves actual records for those buckets.
- Server: Sends
SYNC_DIFF { records: [...] }. - Client: Merges records using LWW.
map.merge(key, record).
Active when Online.
- Event: Another client (or backend process) modifies data.
- Server: Publishes
EVT_MAP_CHANGED.{ "key": "user:555", "val": "...", "hlc": "..." } - Client:
- Checks
localRecord.hlc < evt.hlc. - Updates local Store & LWW-Map.
- Emits
entryUpdatedevent to UI listeners.
- Checks
- Format: MessagePack is recommended over JSON for binary efficiency and date handling.
- Schema: The system should support schema-less (JSON documents) by default, but allow typed Compact serialization for performance-critical maps.