Skip to content

Conversation

@KyleAMathews
Copy link
Collaborator

🎯 Changes

This PR adds two new public APIs to the CollectionImpl class to enable introspection of synced (server-side) state, independent of optimistic updates:

  1. getSyncedValue(key) - Returns the authoritative server-side value for a given key, ignoring any pending optimistic mutations. This allows applications to detect server-side changes and implement conflict resolution strategies.

  2. getSyncedMetadata(key) - Returns sync metadata (e.g., revision numbers, ETags) associated with a synced entity, useful for version-based conflict detection.

These APIs enable robust conflict detection in paced mutations by allowing the mutationFn to compare the original mutation state against the current server state before persisting changes. The PR includes comprehensive test coverage demonstrating:

  • Basic synced value retrieval
  • Behavior with optimistic updates, inserts, and deletes
  • Server-side update reflection
  • Metadata management and merging
  • Conflict detection and resolution strategies in paced mutations
  • Merge strategies when server data diverges

Additionally, the paced mutations implementation is hardened to gracefully handle external transaction rollbacks (e.g., from cascade conflicts or manual rollback). When a debounce fires after a transaction has been externally cancelled, the strategy callback now safely returns early instead of throwing an error, and the next mutate() call creates a fresh transaction.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.

https://claude.ai/code/session_01FPgcCTxP2SC8NTeWx9xhJV

…te conflicts

When using paced/debounced mutations alongside server-side updates (e.g.,
from websockets), pending optimistic mutations can overwrite incoming
server state. This adds a `rollbackOptimisticUpdates(keys?)` method on
Collection that cancels pending transactions for specific keys (or all
keys), allowing the server update to take precedence.

Also makes the paced mutations commit callback resilient to externally
rolled-back transactions — instead of throwing when the debounce/throttle
timer fires after a rollback, it silently clears the reference and allows
the next mutation to create a fresh transaction.

https://claude.ai/code/session_01FPgcCTxP2SC8NTeWx9xhJV
…paced mutations

Replace rollbackOptimisticUpdates with synced state introspection. Rolling
back optimistic updates would yank controlled input state out from under
the user mid-keystroke. Instead, expose the server-side state so the
mutationFn can detect conflicts at persist time and reconcile (merge,
skip, or retry) without disrupting the UI.

- `collection.getSyncedValue(key)` — returns the authoritative server
  value for a key, ignoring optimistic overlays
- `collection.getSyncedMetadata(key)` — returns sync metadata (revision
  numbers, ETags, etc.) for conflict detection

The paced mutations commit callback is also made resilient to externally
rolled-back transactions (e.g. via manual tx.rollback() or cascade) so
the debounce/throttle timer doesn't throw.

https://claude.ai/code/session_01FPgcCTxP2SC8NTeWx9xhJV
@changeset-bot
Copy link

changeset-bot bot commented Feb 12, 2026

⚠️ No Changeset found

Latest commit: 2163ae3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants