Skip to content

Architecture

How state-sync keeps app state consistent across windows, tabs, and processes.

High-level overview

state-sync implements an invalidation-pull protocol: a lightweight event signals that state may have changed, and the receiver pulls the latest snapshot on demand.

Package structure

All framework and transport adapters depend only on @statesync/core. The persistence layer is optional.

Core protocol

The sync engine follows a strict sequence to guarantee consistency:

Coalescing strategy

When multiple invalidation events arrive in rapid succession, the engine coalesces them to prevent refresh spam:

This means even 100 events firing in a burst result in at most 2 refreshes — not 100.

Data flow with persistence

When the persistence layer is enabled, it wraps the applier to add storage, compression, and cross-tab broadcast:

Startup sequence

Revision comparison

Revisions are canonical u64 decimal strings ("0", "42", up to "18446744073709551615"). Comparison is length-first, then lexicographic:

No cryptographic hashing. No timestamps. Just monotonic integers — simple and reliable.

Error handling phases

The engine reports errors with structured context, including which phase of the sync cycle failed:

Each error includes phase, topic, localRevision, error, and optional eventRevision / snapshotRevision — making debugging straightforward.

Design principles

PrincipleHow it's applied
Transport-agnosticCore knows nothing about Tauri, WebSocket, or BroadcastChannel. You provide a subscriber + provider.
Framework-agnosticCore knows nothing about Pinia, Zustand, or Vue. You provide an applier.
Source of truthOne canonical backend per topic. All windows pull from the same provider. No circular sync.
Revision orderingMonotonic u64 revisions. Stale events are rejected before any network call.
CoalescingRapid bursts collapse into at most 2 refreshes (current + 1 queued). No thundering herd.
ThrottlingOptional debounce/throttle layer controls refresh rate for high-frequency invalidation.
Graceful degradationMissing BroadcastChannel? No-op. Failed apply? Continue syncing. Every error is reported, nothing crashes.
Tiny footprintCore is 3.1 KB gzipped. Each adapter is ~0.8 KB.

Released under the MIT License.