Skip to content

fix(query-devtools/utils): make 'last updated' sort return 0 for queries with equal 'dataUpdatedAt' to follow the standard comparator contract#10812

Open
sukvvon wants to merge 1 commit into
mainfrom
fix/query-devtools-sort-fns-date-sort-equal-timestamp
Open

fix(query-devtools/utils): make 'last updated' sort return 0 for queries with equal 'dataUpdatedAt' to follow the standard comparator contract#10812
sukvvon wants to merge 1 commit into
mainfrom
fix/query-devtools-sort-fns-date-sort-equal-timestamp

Conversation

@sukvvon
Copy link
Copy Markdown
Collaborator

@sukvvon sukvvon commented May 28, 2026

🎯 Changes

The devtools 'last updated' sort (dateSort in utils.tsx:104-105) was implemented as a binary comparator:

const dateSort: SortFn = (a, b) =>
  a.state.dataUpdatedAt < b.state.dataUpdatedAt ? 1 : -1

This breaks the standard Array.prototype.sort comparator contract for equal inputs — for a.dataUpdatedAt === b.dataUpdatedAt, the function still returns -1 instead of 0, so V8's stable sort cannot preserve the input order between two queries that were updated at the same millisecond. The implementation also relies on a strict < check, which means a future dataUpdatedAt of NaN would silently fall into the -1 branch.

Rewrite dateSort to the canonical descending comparator (most recently updated first) using a single subtraction plus an explicit ternary, so the function returns -1, 0, or 1:

const dateSort: SortFn = (a, b) => {
  const diff = b.state.dataUpdatedAt - a.state.dataUpdatedAt
  return diff < 0 ? -1 : diff > 0 ? 1 : 0
}
  • Same-millisecond queries now compare equal (0), so stable sort keeps their relative input order.
  • The intent (newer first) is preserved unchanged.
  • NaN/Infinity inputs fall through to the 0 branch instead of returning a non--1/0/1 value, which keeps the comparator deterministic.

Also add an expect(dateSort(a, b)).toBe(0) regression case to utils.test.ts so the equal-timestamp branch fails loudly if the binary form is reintroduced. The existing .toBe(1) / .toBe(-1) assertions still hold because the new implementation still emits -1/1 for the unequal cases.

✅ Checklist

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

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Bug Fixes
    • Fixed the "last updated" sorting functionality in the devtools query panel to correctly handle scenarios where queries have equal update timestamps. The sort now properly returns equal status when data update timestamp values match, ensuring full compliance with standard comparator conventions and improving overall consistency and predictability of sorting results.

Review Change Stack

…ies with equal 'dataUpdatedAt' to follow the standard comparator contract
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 80ddb2e7-97a2-407c-a252-68a1c4b30c4c

📥 Commits

Reviewing files that changed from the base of the PR and between 3daac67 and a7eccf3.

📒 Files selected for processing (3)
  • .changeset/devtools-date-sort-equal-timestamps.md
  • packages/query-devtools/src/__tests__/utils.test.ts
  • packages/query-devtools/src/utils.tsx

📝 Walkthrough

Walkthrough

The PR fixes a bug in the query DevTools where the "last updated" sort comparator was not properly handling equal timestamps. The implementation is corrected to return 0 when two queries have the same dataUpdatedAt value, a test case validates the fix, and a changeset documents the patch release.

Changes

Date Sort Equality Fix

Layer / File(s) Summary
Sort comparator equality fix
packages/query-devtools/src/utils.tsx, packages/query-devtools/src/__tests__/utils.test.ts, .changeset/devtools-date-sort-equal-timestamps.md
The dateSort comparator is refactored from a comparison-style expression that never returned 0 to a subtraction-based implementation that correctly returns 0 for equal dataUpdatedAt values. A unit test validates this behavior for the "last updated" sort, and a changeset documents the patch release.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Suggested labels

package: query-devtools

Suggested reviewers

  • TkDodo

Poem

🐰 A timestamp that's equal should equal its peer,
No more -1 when they're the same, that's clear!
The sort returns zero, the contract's restored,
With tests to ensure this bug is no more! 🎯

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: fixing the 'last updated' sort to return 0 for equal timestamps, which is a clear and specific description of the primary fix.
Description check ✅ Passed The description covers all required sections from the template: detailed changes explanation with before/after code, completed checklist items, and release impact marked correctly with a changeset generated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/query-devtools-sort-fns-date-sort-equal-timestamp

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 28, 2026

View your CI Pipeline Execution ↗ for commit a7eccf3

Command Status Duration Result
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 30s View ↗
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 2m 58s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-28 02:16:29 UTC

@github-actions
Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

2 package(s) bumped directly, 23 bumped as dependents.

🟩 Patch bumps

Package Version Reason
@tanstack/lit-query 0.2.6 → 0.2.7 Changeset
@tanstack/query-devtools 5.100.14 → 5.100.15 Changeset
@tanstack/angular-query-experimental 5.100.14 → 5.100.15 Dependent
@tanstack/angular-query-persist-client 5.100.14 → 5.100.15 Dependent
@tanstack/eslint-plugin-query 5.100.14 → 5.100.15 Dependent
@tanstack/preact-query 5.100.14 → 5.100.15 Dependent
@tanstack/preact-query-devtools 5.100.14 → 5.100.15 Dependent
@tanstack/preact-query-persist-client 5.100.14 → 5.100.15 Dependent
@tanstack/query-async-storage-persister 5.100.14 → 5.100.15 Dependent
@tanstack/query-broadcast-client-experimental 5.100.14 → 5.100.15 Dependent
@tanstack/query-core 5.100.14 → 5.100.15 Dependent
@tanstack/query-persist-client-core 5.100.14 → 5.100.15 Dependent
@tanstack/query-sync-storage-persister 5.100.14 → 5.100.15 Dependent
@tanstack/react-query 5.100.14 → 5.100.15 Dependent
@tanstack/react-query-devtools 5.100.14 → 5.100.15 Dependent
@tanstack/react-query-next-experimental 5.100.14 → 5.100.15 Dependent
@tanstack/react-query-persist-client 5.100.14 → 5.100.15 Dependent
@tanstack/solid-query 5.100.14 → 5.100.15 Dependent
@tanstack/solid-query-devtools 5.100.14 → 5.100.15 Dependent
@tanstack/solid-query-persist-client 5.100.14 → 5.100.15 Dependent
@tanstack/svelte-query 6.1.33 → 6.1.34 Dependent
@tanstack/svelte-query-devtools 6.1.33 → 6.1.34 Dependent
@tanstack/svelte-query-persist-client 6.1.33 → 6.1.34 Dependent
@tanstack/vue-query 5.100.14 → 5.100.15 Dependent
@tanstack/vue-query-devtools 6.1.33 → 6.1.34 Dependent

@sukvvon sukvvon self-assigned this May 28, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 28, 2026

More templates

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@10812

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@10812

@tanstack/lit-query

npm i https://pkg.pr.new/@tanstack/lit-query@10812

@tanstack/preact-query

npm i https://pkg.pr.new/@tanstack/preact-query@10812

@tanstack/preact-query-devtools

npm i https://pkg.pr.new/@tanstack/preact-query-devtools@10812

@tanstack/preact-query-persist-client

npm i https://pkg.pr.new/@tanstack/preact-query-persist-client@10812

@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@10812

@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@10812

@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@10812

@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@10812

@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@10812

@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@10812

@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@10812

@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@10812

@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@10812

@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@10812

@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@10812

@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@10812

@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@10812

@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@10812

@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@10812

@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@10812

@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@10812

@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@10812

commit: a7eccf3

@github-actions
Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size
react full 12.11 KB (0%)
react minimal 9.08 KB (0%)

@sukvvon sukvvon requested a review from TkDodo May 28, 2026 05:13
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.

1 participant