PAM Native Sync
pam add syncpam doctor$engine = new SyncEngine( new SQLiteSyncStore(), $transport, new PolicyConflictResolver(ConflictPolicy::LastWriteWins),);$engine->upsert('todos', 'todo-42', ['title' => 'Ship'], 7, fn ($operation) => null);$engine->synchronize(fn (SyncRunReport $report) => null);SyncEngine queues local mutations and coordinates push/pull;
SQLiteSyncStore persists outbox/cursor/replicas/attempts/tombstones;
SyncTransport is provider-neutral; conflict resolvers make decisions;
SyncRunReport summarizes state/counts/conflicts.
Use stable idempotency IDs, monotonic server versions, transactional remote changes plus cursor advancement, explicit retry/tombstone policy, and a domain conflict strategy. HTTP, Realtime, and Laravel adapters remain separate packages—the engine is not a database wrapper or hidden transport.
Complete synchronization contracts
Section titled “Complete synchronization contracts”SyncStore is the persistence interface; implementations are
SQLiteSyncStore and InMemorySyncStore. SyncOperation represents queued
intent, RemoteChange represents server state, and SyncPushResult /
SyncPullResult are transport outcomes. Implement ConflictResolver for
domain-specific resolution or use PolicyConflictResolver for a declared
policy.
SyncOperationKind uses Upsert=1 and Delete=2; SyncOperationState uses
Pending=1, InFlight=2, Acknowledged=3, Failed=4; SyncRunState uses
Succeeded=1, Partial=2, Failed=3. SyncPluginProvider registers the
engine integration.