Skip to content

ref(tsc): useReleasesWidgetQuery to apiOptions#114427

Merged
TkDodo merged 2 commits intomasterfrom
tkdodo/ref/useReleasesWidgetQuery-to-apiOptions
May 4, 2026
Merged

ref(tsc): useReleasesWidgetQuery to apiOptions#114427
TkDodo merged 2 commits intomasterfrom
tkdodo/ref/useReleasesWidgetQuery-to-apiOptions

Conversation

@TkDodo
Copy link
Copy Markdown
Collaborator

@TkDodo TkDodo commented Apr 30, 2026

Migrate the useReleasesSeriesQuery and useReleasesTableQuery hooks (the /sessions/ and /metrics/data/ callers behind release-health widget cards) onto apiOptions so their results live in the v2 query cache.

The widgets previously built v1 query keys by hand and dispatched via doSessionsRequest / doReleaseHealthRequest, which used api.requestPromise directly and never participated in the structured cache. To keep the existing imperative call site (projectAnrScoreCard.tsx) working without a behavior change, both action creators now share their URL-query construction with two new factories:

  • sessionsApiOptions(options)apiOptions.as<SessionApiResponse>()('/organizations/$organizationIdOrSlug/sessions/', ...)
  • releaseHealthApiOptions(options)apiOptions.as<SessionApiResponse>()('/organizations/$organizationIdOrSlug/metrics/data/', ...)

useReleasesWidgetQuery.tsx picks the factory based on requestData.useSessionAPI, then overrides queryFn with the existing queue-wrapping pattern (calling apiFetch instead of the imperative wrappers). select: selectJsonWithHeaders exposes both the JSON body and the Link header used for pagination. Result-access in the transform block updates from the v1 tuple to v2 shape (q.data?.[0]q.data?.json, responseMeta?.getResponseHeader('Link')q.data.headers.Link).

projectAnrScoreCard.tsx is also rewritten to consume sessionsApiOptions directly via useQuery, replacing the two ad-hoc useEffect + manual setState blocks with cached queries that get cancellation and dedup for free.

The remaining ~17 other callers of /sessions/ (insights hooks, project score cards, releases pages, charts) are intentionally left on v1 for now: there are no invalidateQueries / setQueryData predicates that match this URL anywhere in the codebase, and each caller's query params produce a distinct cache slot, so a v1/v2 mix is independent — no leak, no clobber. Migrating them is mechanical follow-up work, not a correctness gate for this change.

@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Apr 30, 2026
@TkDodo
Copy link
Copy Markdown
Collaborator Author

TkDodo commented Apr 30, 2026

bugbot run

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 309ea1e. Configure here.

@TkDodo TkDodo marked this pull request as ready for review April 30, 2026 15:01
@TkDodo TkDodo requested review from a team as code owners April 30, 2026 15:01
@TkDodo TkDodo requested a review from a team April 30, 2026 15:01
if (queue) {
return new Promise((resolve, reject) => {
const fetchFnRef = {
current: () =>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

:wat:

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

📊 Type Coverage Diff

✅ No new type safety issues introduced. Coverage: 93.40%

@TkDodo TkDodo merged commit fb00566 into master May 4, 2026
73 checks passed
@TkDodo TkDodo deleted the tkdodo/ref/useReleasesWidgetQuery-to-apiOptions branch May 4, 2026 14:28
cleptric pushed a commit that referenced this pull request May 5, 2026
Migrate the `useReleasesSeriesQuery` and `useReleasesTableQuery` hooks
(the `/sessions/` and `/metrics/data/` callers behind release-health
widget cards) onto `apiOptions` so their results live in the v2 query
cache.

The widgets previously built v1 query keys by hand and dispatched via
`doSessionsRequest` / `doReleaseHealthRequest`, which used
`api.requestPromise` directly and never participated in the structured
cache. To keep the existing imperative call site
(`projectAnrScoreCard.tsx`) working without a behavior change, both
action creators now share their URL-query construction with two new
factories:

- `sessionsApiOptions(options)` →
`apiOptions.as<SessionApiResponse>()('/organizations/$organizationIdOrSlug/sessions/',
...)`
- `releaseHealthApiOptions(options)` →
`apiOptions.as<SessionApiResponse>()('/organizations/$organizationIdOrSlug/metrics/data/',
...)`

`useReleasesWidgetQuery.tsx` picks the factory based on
`requestData.useSessionAPI`, then overrides `queryFn` with the existing
queue-wrapping pattern (calling `apiFetch` instead of the imperative
wrappers). `select: selectJsonWithHeaders` exposes both the JSON body
and the `Link` header used for pagination. Result-access in the
transform block updates from the v1 tuple to v2 shape (`q.data?.[0]` →
`q.data?.json`, `responseMeta?.getResponseHeader('Link')` →
`q.data.headers.Link`).

`projectAnrScoreCard.tsx` is also rewritten to consume
`sessionsApiOptions` directly via `useQuery`, replacing the two ad-hoc
`useEffect` + manual `setState` blocks with cached queries that get
cancellation and dedup for free.

The remaining `~17` other callers of `/sessions/` (insights hooks,
project score cards, releases pages, charts) are intentionally left on
v1 for now: there are no `invalidateQueries` / `setQueryData` predicates
that match this URL anywhere in the codebase, and each caller's `query`
params produce a distinct cache slot, so a v1/v2 mix is independent — no
leak, no clobber. Migrating them is mechanical follow-up work, not a
correctness gate for this change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants