Skip to content

fix(base-data-service): adapt to @tanstack/query-core v5 API - #9712

Open
cryptodev-2s wants to merge 8 commits into
mainfrom
fix/query-core-v5-base-data-service
Open

fix(base-data-service): adapt to @tanstack/query-core v5 API#9712
cryptodev-2s wants to merge 8 commits into
mainfrom
fix/query-core-v5-base-data-service

Conversation

@cryptodev-2s

@cryptodev-2s cryptodev-2s commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

What

Stacked on top of #9686. That PR bumps @tanstack/query-core this adapts the code to v5.

Changes

packages/base-data-service/src/BaseDataService.ts

  • invalidateQueries filter type: in v5 the generic is the query key (constrained to readonly unknown[]), not page data, so InvalidateQueryFilters<Json> no longer type checks. Dropped the argument to keep the loose v4 ergonomics.
  • queryFn can now be the skipToken sentinel (a unique symbol, not callable). Typed the options so queryFn is always a concrete function, since data services never use skipToken.
  • fetchInfiniteQuery: v5 requires initialPageParam, and fetchMore meta no longer carries an explicit pageParam (v5 derives it from getNextPageParam / getPreviousPageParam). Now passes initialPageParam and injects page param resolvers at query.fetch time so pagination still fetches the exact requested page. This keeps cursor pagination working even for consumers that do not define page param callbacks.

packages/chomp-api-service/src/chomp-api-service.ts

  • cacheTime was renamed to gcTime in v5. Without this, the "evict on settle" behavior stopped working.

Tests / helpers

  • hashQueryKey was renamed to hashKey.
  • dehydrate now writes a dehydratedAt field into query state.
  • Renamed cacheTime to gcTime and typed the page param in the example service.

Why the injection matters

MoneyAccountApiDataService paginates via an explicit cursor without defining getNextPageParam. Under the raw v5 bump its pagination test crashed with options.getNextPageParam is not a function. The resolver injection restores that behavior.


Note

Medium Risk
Breaking dependency and API surface on shared BaseDataService pagination/cache behavior; incorrect infinite-query shims could regress cursor paging or cache eviction for multiple API services.

Overview
Breaking upgrade of @tanstack/query-core from v4 to v5 across base-data-service and dependent packages (chomp-api, money-account-api, sentinel, sample-controllers, wallet-framework-docs).

BaseDataService is updated so query APIs match v5: invalidateQueries no longer uses the old InvalidateQueryFilters<Json> typing; fetchQuery / fetchInfiniteQuery require a real queryFn (v5’s skipToken is excluded). fetchInfiniteQuery is reworked for v5’s infinite-query rules—initialPageParam is supplied, and because v5 no longer passes an explicit page via fetchMore meta, the base layer injects getNextPageParam / getPreviousPageParam at fetch time (plus a no-op next-page resolver when callers omit callbacks) so explicit cursor pagination still works for services like Money Account API that don’t define page-param callbacks.

Downstream call sites rename cacheTimegcTime (e.g. Chomp getAssociatedAddresses eviction). Tests switch hashQueryKeyhashKey, expect dehydratedAt on persisted queries, and add dedicated fetchInfiniteQuery coverage for forward/backward paging with and without callbacks.

Reviewed by Cursor Bugbot for commit 5a1dcce. Bugbot is set up for automated code reviews on this repo. Configure here.

@cryptodev-2s
cryptodev-2s changed the base branch from update-tanstack-query-core-v5 to main August 3, 2026 21:46
@cryptodev-2s
cryptodev-2s force-pushed the fix/query-core-v5-base-data-service branch from def5a29 to 88ec84f Compare August 3, 2026 21:46
@cryptodev-2s
cryptodev-2s marked this pull request as ready for review August 4, 2026 10:09
@cryptodev-2s
cryptodev-2s force-pushed the fix/query-core-v5-base-data-service branch from 637de58 to 6dbe63d Compare August 4, 2026 10:09
@cryptodev-2s
cryptodev-2s requested review from a team as code owners August 4, 2026 10:09
@cryptodev-2s

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

Comment thread packages/base-data-service/src/BaseDataService.ts
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.5-preview-7b60eca
@metamask-previews/accounts-controller@39.0.6-preview-7b60eca
@metamask-previews/address-book-controller@7.1.2-preview-7b60eca
@metamask-previews/ai-controllers@0.8.0-preview-7b60eca
@metamask-previews/analytics-controller@2.0.0-preview-7b60eca
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-7b60eca
@metamask-previews/announcement-controller@8.1.0-preview-7b60eca
@metamask-previews/app-metadata-controller@2.0.1-preview-7b60eca
@metamask-previews/approval-controller@9.0.2-preview-7b60eca
@metamask-previews/assets-controller@13.1.0-preview-7b60eca
@metamask-previews/assets-controllers@110.1.0-preview-7b60eca
@metamask-previews/authenticated-user-storage@3.0.1-preview-7b60eca
@metamask-previews/base-controller@9.1.0-preview-7b60eca
@metamask-previews/base-data-service@0.1.3-preview-7b60eca
@metamask-previews/bitcoin-regtest-up@1.0.0-preview-7b60eca
@metamask-previews/bridge-controller@78.0.3-preview-7b60eca
@metamask-previews/bridge-status-controller@74.6.1-preview-7b60eca
@metamask-previews/build-utils@3.0.4-preview-7b60eca
@metamask-previews/chain-agnostic-permission@1.7.0-preview-7b60eca
@metamask-previews/chomp-api-service@4.0.0-preview-7b60eca
@metamask-previews/claims-controller@0.5.3-preview-7b60eca
@metamask-previews/client-controller@1.0.1-preview-7b60eca
@metamask-previews/client-utils@1.6.0-preview-7b60eca
@metamask-previews/compliance-controller@2.1.0-preview-7b60eca
@metamask-previews/composable-controller@12.0.1-preview-7b60eca
@metamask-previews/config-registry-controller@2.0.0-preview-7b60eca
@metamask-previews/connectivity-controller@0.3.0-preview-7b60eca
@metamask-previews/controller-utils@12.3.0-preview-7b60eca
@metamask-previews/core-backend@8.1.0-preview-7b60eca
@metamask-previews/delegation-controller@3.0.2-preview-7b60eca
@metamask-previews/earn-controller@12.2.3-preview-7b60eca
@metamask-previews/eip-5792-middleware@3.0.5-preview-7b60eca
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-7b60eca
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-7b60eca
@metamask-previews/ens-controller@19.1.6-preview-7b60eca
@metamask-previews/eth-block-tracker@15.0.1-preview-7b60eca
@metamask-previews/eth-json-rpc-middleware@24.0.0-preview-7b60eca
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-7b60eca
@metamask-previews/foundryup@1.0.1-preview-7b60eca
@metamask-previews/gas-fee-controller@26.3.1-preview-7b60eca
@metamask-previews/gator-permissions-controller@5.0.1-preview-7b60eca
@metamask-previews/geolocation-controller@1.0.0-preview-7b60eca
@metamask-previews/java-tron-up@1.0.0-preview-7b60eca
@metamask-previews/json-rpc-engine@10.5.0-preview-7b60eca
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-7b60eca
@metamask-previews/keyring-controller@27.1.0-preview-7b60eca
@metamask-previews/local-node-utils@1.0.0-preview-7b60eca
@metamask-previews/logging-controller@8.0.2-preview-7b60eca
@metamask-previews/message-manager@14.1.2-preview-7b60eca
@metamask-previews/messenger@2.0.0-preview-7b60eca
@metamask-previews/messenger-cli@0.2.0-preview-7b60eca
@metamask-previews/money-account-api-data-service@0.4.0-preview-7b60eca
@metamask-previews/money-account-balance-service@2.4.1-preview-7b60eca
@metamask-previews/money-account-controller@0.3.3-preview-7b60eca
@metamask-previews/money-account-upgrade-controller@3.0.1-preview-7b60eca
@metamask-previews/money-account-utils@1.1.0-preview-7b60eca
@metamask-previews/multichain-account-service@13.0.0-preview-7b60eca
@metamask-previews/multichain-api-middleware@4.0.2-preview-7b60eca
@metamask-previews/multichain-network-controller@3.2.2-preview-7b60eca
@metamask-previews/multichain-transactions-controller@7.1.1-preview-7b60eca
@metamask-previews/name-controller@9.1.2-preview-7b60eca
@metamask-previews/network-connection-banner-controller@0.1.2-preview-7b60eca
@metamask-previews/network-controller@35.0.1-preview-7b60eca
@metamask-previews/network-enablement-controller@6.0.2-preview-7b60eca
@metamask-previews/notification-services-controller@26.0.0-preview-7b60eca
@metamask-previews/passkey-controller@3.0.0-preview-7b60eca
@metamask-previews/permission-controller@13.1.1-preview-7b60eca
@metamask-previews/permission-log-controller@5.1.0-preview-7b60eca
@metamask-previews/perps-controller@10.0.0-preview-7b60eca
@metamask-previews/phishing-controller@17.3.1-preview-7b60eca
@metamask-previews/platform-api-docs@0.0.0-preview-7b60eca
@metamask-previews/polling-controller@16.0.9-preview-7b60eca
@metamask-previews/preferences-controller@23.1.0-preview-7b60eca
@metamask-previews/profile-metrics-controller@4.0.2-preview-7b60eca
@metamask-previews/profile-sync-controller@28.3.0-preview-7b60eca
@metamask-previews/ramps-controller@18.0.1-preview-7b60eca
@metamask-previews/rate-limit-controller@7.0.1-preview-7b60eca
@metamask-previews/react-data-query@0.2.2-preview-7b60eca
@metamask-previews/remote-feature-flag-controller@5.0.0-preview-7b60eca
@metamask-previews/sample-controllers@5.0.4-preview-7b60eca
@metamask-previews/seedless-onboarding-controller@10.1.0-preview-7b60eca
@metamask-previews/selected-network-controller@26.1.6-preview-7b60eca
@metamask-previews/sentinel-api-service@1.0.0-preview-7b60eca
@metamask-previews/shield-controller@5.1.3-preview-7b60eca
@metamask-previews/signature-controller@39.2.9-preview-7b60eca
@metamask-previews/smart-transactions-controller@25.0.2-preview-7b60eca
@metamask-previews/snap-account-service@2.1.1-preview-7b60eca
@metamask-previews/social-controllers@2.7.0-preview-7b60eca
@metamask-previews/solana-test-validator-up@1.0.0-preview-7b60eca
@metamask-previews/stellar-quickstart-up@0.0.0-preview-7b60eca
@metamask-previews/storage-service@1.0.2-preview-7b60eca
@metamask-previews/subscription-controller@6.2.1-preview-7b60eca
@metamask-previews/transaction-controller@69.4.0-preview-7b60eca
@metamask-previews/transaction-pay-controller@26.2.0-preview-7b60eca
@metamask-previews/user-operation-controller@41.2.8-preview-7b60eca
@metamask-previews/wallet@9.0.0-preview-7b60eca
@metamask-previews/wallet-cli@0.0.0-preview-7b60eca

cryptodev-2s added a commit that referenced this pull request Aug 4, 2026
… param callbacks

query-core v5 walks `getNextPageParam` when it refetches an infinite query
that has more than one page cached. Consumers that paginate by explicit
cursor without defining `getNextPageParam` (like `MoneyAccountApiDataService`)
would throw once a second page was cached and a stale refetch with no page
param ran.

Default `getNextPageParam` to a resolver that returns `null` so the refetch
rebuilds just the first page instead of throwing. The consumer repopulates
the cache by navigating again with explicit page params.

Also adds a `fetchInfiniteQuery` test suite covering forward and backward
navigation with and without page param callbacks, single page returns,
`staleTime` deduplication, and this refetch regression.

Flagged by Cursor Bugbot on #9712.
Gudahtt and others added 8 commits August 4, 2026 14:13
A recent PR updated this package to v5 in one package (#9563). This PR
updates to v5 in all remaining packages.
The v5 bump updated the package.json versions but left the v4 API usage
in place, so the build fails. This adapts the code to v5.

* `invalidateQueries` filter: the generic is now the query key (not page
  data), so drop the `Json` argument
* handle the new `skipToken` sentinel by typing `queryFn` as a concrete
  function (data services never use it)
* `fetchInfiniteQuery`: pass `initialPageParam` and inject page param
  resolvers at fetch time, since v5 no longer accepts an explicit
  `pageParam` via `fetchMore` meta. This keeps cursor pagination working
  for consumers that do not define page param callbacks
* chomp: `cacheTime` is now `gcTime`
* tests: `hashQueryKey` is now `hashKey`, and `dehydrate` adds a
  `dehydratedAt` field
… param callbacks

query-core v5 walks `getNextPageParam` when it refetches an infinite query
that has more than one page cached. Consumers that paginate by explicit
cursor without defining `getNextPageParam` (like `MoneyAccountApiDataService`)
would throw once a second page was cached and a stale refetch with no page
param ran.

Default `getNextPageParam` to a resolver that returns `null` so the refetch
rebuilds just the first page instead of throwing. The consumer repopulates
the cache by navigating again with explicit page params.

Also adds a `fetchInfiniteQuery` test suite covering forward and backward
navigation with and without page param callbacks, single page returns,
`staleTime` deduplication, and this refetch regression.

Flagged by Cursor Bugbot on #9712.
@cryptodev-2s
cryptodev-2s force-pushed the fix/query-core-v5-base-data-service branch from 4561b46 to 5a1dcce Compare August 4, 2026 13:13

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5a1dcce. Configure here.

// query-core v5 requires an `initialPageParam`. When the caller drives
// pagination with an explicit `pageParam`, use it as the initial param
// so the first (and only) page fetched is the requested one.
initialPageParam: (options.initialPageParam ?? pageParam) as TPageParam,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Null initial page param discarded

Medium Severity

initialPageParam is resolved with ??, so an explicit null is treated as missing and replaced by pageParam or undefined. null is a valid Json page param and the usual v5 first-page sentinel, so callers that set initialPageParam: null never get that value stored or passed through.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5a1dcce. Configure here.

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