Skip to main content

Universal SQLite Synchronization Core - A dependency-grade, local-first, offline-first SQLite synchronization primitive

Project description

Universal SQLite Synchronization Core

Python 3.11+ License: AGPL-3.0 Status: Production Ready

A product of VisionQuantech, India ๐Ÿ‡ฎ๐Ÿ‡ณ

A dependency-grade, local-first, offline-first SQLite synchronization primitive.

Captures database changes as structured operations, packages them into self-contained bundles, and applies them deterministically across disconnected devices.


Features

  • ๐Ÿ”’ Append-only log โ€“ Operations are immutable history
  • ๐Ÿ• Vector clocks โ€“ Causality tracking across devices
  • โš”๏ธ Conflict detection โ€“ Never auto-merges, preserves conflicts
  • ๐Ÿ”„ Deterministic replay โ€“ Same operations = same result everywhere
  • ๐Ÿ“ฆ Transport agnostic โ€“ Bundles work over USB, email, Bluetooth, anything
  • ๐Ÿšซ Zero infrastructure โ€“ No servers, no cloud, no network required

Installation

From PyPI

pip install sqlite-sync-core

From GitHub (Development)

git clone https://github.com/shivay00001/sqlite-sync-core.git
cd sqlite-sync-core
pip install -e .

Real-Time Network Sync

SQLite Sync Core now supports real-time synchronization over WebSockets.

Start the Reference Server

python -m sqlite_sync.network.server

Connect a Client

from sqlite_sync import SyncEngine
from sqlite_sync.network.client import SyncClient

engine = SyncEngine("my_app.db")
engine.initialize()

client = SyncClient(engine, "ws://localhost:8765")
await client.connect()

# Listen for remote changes
asyncio.create_task(client.listen())

# Send local changes
ops = engine.get_new_operations()
for op in ops:
    await client.send_operation(op)

Integration Examples

See the examples/ directory for full integration samples:

  • basic_usage.py: Simple CLI setup.
  • network_sync.py: Real-time sync between two peers.
  • desktop_example.py: Coming soon (GUI integration).

Requirements

  • Python 3.11+
  • msgpack (auto-installed)

Quick Start

from sqlite_sync import SyncEngine

# Initialize sync-enabled database
engine = SyncEngine("my_database.db")
engine.initialize()

# Create a user table
engine.connection.execute("""
    CREATE TABLE todos (
        id INTEGER PRIMARY KEY,
        title TEXT NOT NULL,
        done INTEGER DEFAULT 0
    )
""")

# Enable sync for the table
engine.enable_sync_for_table("todos")

# Now any INSERT/UPDATE/DELETE is automatically captured!
engine.connection.execute("INSERT INTO todos (title) VALUES ('Buy milk')")

Syncing Between Devices

Device A: Generate a bundle

from sqlite_sync import SyncEngine

engine_a = SyncEngine("device_a.db")
engine_a.initialize()

# Generate bundle for Device B
bundle_path = engine_a.generate_bundle(
    peer_device_id=device_b_id,  # 16-byte UUID
    output_path="sync_bundle.db"
)
# Send bundle_path to Device B (USB, email, cloud, etc.)

Device B: Import the bundle

engine_b = SyncEngine("device_b.db")
engine_b.initialize()

# Import received bundle
result = engine_b.import_bundle("sync_bundle.db")

print(f"Applied: {result.applied_count}")
print(f"Conflicts: {result.conflict_count}")
print(f"Duplicates: {result.duplicate_count}")

Handling Conflicts

Conflicts occur when two devices modify the same row independently.

# Get all unresolved conflicts
conflicts = engine.get_unresolved_conflicts()

for conflict in conflicts:
    print(f"Table: {conflict.table_name}")
    print(f"Row PK: {conflict.row_pk}")
    print(f"Local op: {conflict.local_op_id.hex()}")
    print(f"Remote op: {conflict.remote_op_id.hex()}")

Note: This library intentionally does NOT auto-resolve conflicts. You must implement your own resolution strategy.


Core Invariants

# Invariant Description
1 Append-only sync_operations only grows, never modified
2 Causal consistency Vector clocks ensure happens-before
3 Deterministic ordering Same operations always sort identically
4 Explicit conflicts Concurrent writes preserved as records
5 Idempotent import Same bundle ร— N imports = same result
6 Transport independence Bundles are self-contained SQLite files

API Reference

SyncEngine

Method Description
initialize() Initialize sync tables, returns device ID
enable_sync_for_table(name) Install triggers for a table
generate_bundle(peer_id, path) Create bundle for peer
import_bundle(path) Import bundle, returns ImportResult
get_unresolved_conflicts() Get all pending conflicts
get_vector_clock() Get current vector clock
close() Close database connection

ImportResult

Field Type Description
bundle_id bytes UUID of imported bundle
source_device_id bytes Device that created bundle
total_operations int Total ops in bundle
applied_count int Successfully applied
conflict_count int Conflicts detected
duplicate_count int Already had these ops
skipped bool True if bundle already imported

Project Structure

sqlite_sync_core/
โ”œโ”€โ”€ src/sqlite_sync/
โ”‚   โ”œโ”€โ”€ engine.py          # Main SyncEngine class
โ”‚   โ”œโ”€โ”€ config.py          # Configuration constants
โ”‚   โ”œโ”€โ”€ errors.py          # Exception classes
โ”‚   โ”œโ”€โ”€ invariants.py      # Core invariant enforcement
โ”‚   โ”œโ”€โ”€ db/                # Database layer
โ”‚   โ”‚   โ”œโ”€โ”€ schema.py      # Table definitions
โ”‚   โ”‚   โ”œโ”€โ”€ migrations.py  # Initialization
โ”‚   โ”‚   โ”œโ”€โ”€ triggers.py    # Change capture triggers
โ”‚   โ”‚   โ””โ”€โ”€ connection.py  # Connection management
โ”‚   โ”œโ”€โ”€ bundle/            # Bundle operations
โ”‚   โ”‚   โ”œโ”€โ”€ generate.py    # Bundle creation
โ”‚   โ”‚   โ”œโ”€โ”€ validate.py    # Bundle validation
โ”‚   โ”‚   โ””โ”€โ”€ format.py      # Bundle metadata
โ”‚   โ”œโ”€โ”€ import_apply/      # Import pipeline
โ”‚   โ”‚   โ”œโ”€โ”€ apply.py       # Apply operations
โ”‚   โ”‚   โ”œโ”€โ”€ conflict.py    # Conflict detection
โ”‚   โ”‚   โ”œโ”€โ”€ ordering.py    # Deterministic sort
โ”‚   โ”‚   โ””โ”€โ”€ dedup.py       # Deduplication
โ”‚   โ”œโ”€โ”€ log/               # Operation log
โ”‚   โ”‚   โ”œโ”€โ”€ operations.py  # SyncOperation dataclass
โ”‚   โ”‚   โ””โ”€โ”€ vector_clock.py# Vector clock logic
โ”‚   โ””โ”€โ”€ utils/             # Utilities
โ”‚       โ”œโ”€โ”€ uuid7.py       # UUID v7 generation
โ”‚       โ”œโ”€โ”€ hashing.py     # SHA-256 utilities
โ”‚       โ””โ”€โ”€ msgpack_codec.py# Serialization
โ”œโ”€โ”€ tests/                 # Test suite
โ”œโ”€โ”€ pyproject.toml         # Package config
โ””โ”€โ”€ README.md

Running Tests

# Using the custom test runner (no pytest required)
python run_verification.py

# Or with pytest
pip install pytest
pytest tests/ -v

License

Dual License Model:

Use Case License Cost
Personal projects AGPL-3.0 Free
Open-source projects AGPL-3.0 Free
Educational/Research AGPL-3.0 Free
Commercial / Proprietary Commercial License Paid

Commercial use (closed-source, SaaS, proprietary) requires a paid license.

Contact for licensing:

See LICENSE for full terms.


Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run the test suite
  5. Submit a pull request

Built with โค๏ธ for offline-first applications

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sqlite_sync_core-0.1.0.tar.gz (45.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sqlite_sync_core-0.1.0-py3-none-any.whl (47.8 kB view details)

Uploaded Python 3

File details

Details for the file sqlite_sync_core-0.1.0.tar.gz.

File metadata

  • Download URL: sqlite_sync_core-0.1.0.tar.gz
  • Upload date:
  • Size: 45.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for sqlite_sync_core-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bccc68fc1926124ce98824b849a9a80b93c8d3bf5bdb62dd3bb058b17a83c233
MD5 89ee38d0928aab83ca6d2c1fa5f19535
BLAKE2b-256 71db38329e7dcf98f441d68441a2457d8b0e3263a66e25279c40667364237265

See more details on using hashes here.

File details

Details for the file sqlite_sync_core-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for sqlite_sync_core-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d6218eea5628fe2f54aefc34a7cbb2ce0f678efe46d8d95c9b1ab3ade9c1ae58
MD5 03ec986a58348ada9ca78833908ff4de
BLAKE2b-256 d4497de0cde538e34404c5830276a6c4c53e6b6a91151bca2859992e5e2cc554

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page