Skip to content

Conversation

@samwillis
Copy link
Collaborator

We have experienced various issues with the change events where they could be doubled up or missed. I think this fixes it all...

@samwillis samwillis requested a review from KyleAMathews June 25, 2025 13:05
@changeset-bot
Copy link

changeset-bot bot commented Jun 25, 2025

🦋 Changeset detected

Latest commit: 6172059

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@tanstack/db Patch
@tanstack/db-collections Patch
@tanstack/react-db Patch
@tanstack/vue-db Patch
@tanstack/db-example-react-todo Patch

Not sure what this means? Click here to learn what changesets are.

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jun 25, 2025

@tanstack/db-example-react-todo

npm i https://pkg.pr.new/@tanstack/db@206
npm i https://pkg.pr.new/@tanstack/db-collections@206
npm i https://pkg.pr.new/@tanstack/react-db@206
npm i https://pkg.pr.new/@tanstack/vue-db@206

commit: 6172059

@github-actions
Copy link
Contributor

github-actions bot commented Jun 25, 2025

Size Change: +841 B (+3.19%)

Total Size: 27.2 kB

Filename Size Change
./packages/db/dist/esm/collection.js 6.39 kB +821 B (+14.73%) ⚠️
./packages/db/dist/esm/transactions.js 1.33 kB +20 B (+1.53%)
ℹ️ View Unchanged
Filename Size
./packages/db/dist/esm/deferred.js 230 B
./packages/db/dist/esm/errors.js 150 B
./packages/db/dist/esm/index.js 409 B
./packages/db/dist/esm/proxy.js 3.75 kB
./packages/db/dist/esm/query/compiled-query.js 1.47 kB
./packages/db/dist/esm/query/evaluators.js 1.06 kB
./packages/db/dist/esm/query/extractors.js 870 B
./packages/db/dist/esm/query/functions.js 1.28 kB
./packages/db/dist/esm/query/group-by.js 976 B
./packages/db/dist/esm/query/joins.js 1.14 kB
./packages/db/dist/esm/query/order-by.js 1.42 kB
./packages/db/dist/esm/query/pipeline-compiler.js 878 B
./packages/db/dist/esm/query/query-builder.js 2.14 kB
./packages/db/dist/esm/query/select.js 1.1 kB
./packages/db/dist/esm/query/utils.js 1.13 kB
./packages/db/dist/esm/SortedMap.js 1.24 kB
./packages/db/dist/esm/utils.js 219 B

compressed-size-action::db-package-size

@github-actions
Copy link
Contributor

github-actions bot commented Jun 25, 2025

Size Change: 0 B

Total Size: 822 B

ℹ️ View Unchanged
Filename Size
./packages/react-db/dist/esm/index.js 173 B
./packages/react-db/dist/esm/useLiveQuery.js 409 B
./packages/react-db/dist/esm/useOptimisticMutation.js 240 B

compressed-size-action::react-db-package-size

Copy link
Collaborator

@KyleAMathews KyleAMathews left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

love it!

Claude made me a nice mermaid diagram to analyze the flow:

flowchart TD
    A[User Makes Optimistic Mutation] --> B[Emit Optimistic Change Event]
    B --> C[Transaction State: persisting]
    
    %% NEW: Pre-sync state capture
    C --> D[🆕 capturePreSyncVisibleState]
    D --> E[🆕 Mark recentlySyncedKeys]
    E --> F[🆕 Capture preSyncVisibleState for affected keys]
    
    %% Server responds
    F --> G[Server Response Received]
    G --> H[onTransactionStateChange]
    
    %% First: recomputeOptimisticState (with filtering)
    H --> I{🆕 isCommittingSyncTransactions?}
    I -->|Yes| J[🆕 Skip Redundant Recalculation]
    I -->|No| K[recomputeOptimisticState]
    
    %% IMPROVED: Better event filtering in recompute
    K --> L[🆕 Filter recentlySyncedKeys]
    L --> M[🆕 Filter redundant delete events]
    M --> N[Emit filtered events]
    
    %% Then: commitPendingTransactions (if any pending)
    J --> O[commitPendingTransactions]
    N --> O
    O --> P[🆕 Set isCommittingSyncTransactions = true]
    P --> Q[Apply sync operations to syncedData]
    Q --> R[🆕 Clear optimistic state]
    R --> S[🆕 Recompute remaining active transactions]
    S --> T[🆕 Set isCommittingSyncTransactions = false]
    
    %% NEW: Smart change detection
    T --> U[🆕 Compare preSyncVisibleState vs current state]
    U --> V{🆕 Sync matches optimistic via deepEqual?}
    V -->|Yes| W[🆕 No events emitted - redundant sync]
    V -->|No| X[🆕 Emit actual change events only]
    
    %% Cleanup
    W --> Y[🆕 Clear preSyncVisibleState]
    X --> Y
    Y --> Z[🆕 Microtask: Clear recentlySyncedKeys]
    
    %% Before vs After
    AA[❌ BEFORE: Duplicate Events] --> BB[Delete optimistic state]
    BB --> CC[Insert sync state]
    CC --> DD[User sees confusing duplicate events]
    
    EE[✅ AFTER: Clean Events] --> FF[Smart state comparison]
    FF --> GG[Only emit real changes]
    GG --> HH[User sees smooth updates]
    
    %% Styling
    classDef new fill:#e8f5e8,stroke:#4caf50,stroke-width:3px
    classDef old fill:#ffebee,stroke:#f44336,stroke-width:2px
    classDef good fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
    
    class D,E,F,I,J,L,M,P,R,S,T,U,V,W,X,Y,Z new
    class AA,BB,CC,DD old
    class EE,FF,GG,HH good
Loading

const newVisibleValue = this.get(key) // This returns the new derived state

// Check if this sync operation is redundant with a completed optimistic operation
const completedOp = completedOptimisticOps.get(key)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice optimization! If the synced data is identical, no new renders 🙏

@samwillis samwillis merged commit 0f8a008 into main Jun 25, 2025
4 checks passed
@samwillis samwillis deleted the event-fixes branch June 25, 2025 18:30
@github-actions github-actions bot mentioned this pull request Jun 25, 2025
cursor bot pushed a commit that referenced this pull request Jul 16, 2025
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