From 4c9a978a9c5d22c5745314ebc282966a756f0894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= <4062236+iscekic@users.noreply.github.com> Date: Tue, 20 Oct 2026 02:42:37 +0000 Subject: [PATCH 1/3] build(deps): bump TanStack Query packages to 5.104.3 Move the three TanStack Query catalog pins together so the persist client's ^5.104.3 peer of react-query stays satisfied, regenerate the lockfile, and add the now-required dehydratedAt field to the persisted-client test fixture. --- apps/mobile/src/lib/persist/test-fixtures.ts | 1 + pnpm-lock.yaml | 96 ++++++++++---------- pnpm-workspace.yaml | 6 +- 3 files changed, 52 insertions(+), 51 deletions(-) diff --git a/apps/mobile/src/lib/persist/test-fixtures.ts b/apps/mobile/src/lib/persist/test-fixtures.ts index 8442594a12b..a2ac33431a2 100644 --- a/apps/mobile/src/lib/persist/test-fixtures.ts +++ b/apps/mobile/src/lib/persist/test-fixtures.ts @@ -24,6 +24,7 @@ export function makePersistedClient(data: unknown, buster = ''): PersistedClient { queryHash: hashKey(GET_ME_QUERY_KEY), queryKey: GET_ME_QUERY_KEY, + dehydratedAt: Date.now(), state: { data, dataUpdateCount: 0, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cc887762611..be853850ae8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,14 +25,14 @@ catalogs: specifier: 3.6.2 version: 3.6.2 '@tanstack/query-async-storage-persister': - specifier: 5.100.10 - version: 5.100.10 + specifier: 5.104.3 + version: 5.104.3 '@tanstack/react-query': - specifier: 5.100.10 - version: 5.100.10 + specifier: 5.104.3 + version: 5.104.3 '@tanstack/react-query-persist-client': - specifier: 5.100.10 - version: 5.100.10 + specifier: 5.104.3 + version: 5.104.3 '@trpc/client': specifier: 11.17.0 version: 11.17.0 @@ -362,7 +362,7 @@ importers: version: 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) '@tanstack/react-query': specifier: 'catalog:' - version: 5.100.10(react@19.2.6) + version: 5.104.3(react@19.2.6) '@tanstack/react-virtual': specifier: ^3.14.3 version: 3.14.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -507,7 +507,7 @@ importers: version: link:../../packages/kilo-chat '@kilocode/kilo-chat-hooks': specifier: workspace:* - version: file:packages/kilo-chat-hooks(@tanstack/react-query@5.100.10(react@19.2.3))(react@19.2.3) + version: file:packages/kilo-chat-hooks(@tanstack/react-query@5.104.3(react@19.2.3))(react@19.2.3) '@kilocode/notifications': specifier: workspace:* version: link:../../packages/notifications @@ -537,7 +537,7 @@ importers: version: 1.5.2(react-native@0.86.3(patch_hash=113932fc75a9e6f352c2a0668f6aa2be25e81326b7b96cc47f8420776a1a92f9)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) '@sentry/react-native': specifier: ~8.29.0 - version: 8.29.0(@babel/core@7.29.7)(@expo/config-types@57.0.2)(@expo/config@57.0.9(typescript@7.0.2))(@expo/env@2.4.3)(bufferutil@4.1.0)(dotenv@17.4.2)(expo-router@57.0.24)(expo@57.0.26)(metro-config@0.84.5)(metro-resolver@0.84.5)(open@11.0.0)(promise@8.3.0)(react-native@0.86.3(patch_hash=113932fc75a9e6f352c2a0668f6aa2be25e81326b7b96cc47f8420776a1a92f9)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(rollup@4.62.3)(typescript@7.0.2)(utf-8-validate@6.0.6)(webpack@5.105.4(esbuild@0.28.2)) + version: 8.29.0(@babel/core@7.29.7)(@expo/config-types@57.0.2)(@expo/config@57.0.9(typescript@7.0.2))(@expo/env@2.4.3)(bufferutil@4.1.0)(dotenv@17.4.2)(expo-router@57.0.24)(expo@57.0.26)(metro-config@0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(metro-resolver@0.84.5)(open@11.0.0)(promise@8.3.0)(react-native@0.86.3(patch_hash=113932fc75a9e6f352c2a0668f6aa2be25e81326b7b96cc47f8420776a1a92f9)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(rollup@4.62.3)(typescript@7.0.2)(utf-8-validate@6.0.6)(webpack@5.105.4(esbuild@0.28.2)) '@shopify/flash-list': specifier: 2.3.3 version: 2.3.3(@babel/runtime@7.29.7)(react-native@0.86.3(patch_hash=113932fc75a9e6f352c2a0668f6aa2be25e81326b7b96cc47f8420776a1a92f9)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3) @@ -546,19 +546,19 @@ importers: version: 4.3.3 '@tanstack/query-async-storage-persister': specifier: 'catalog:' - version: 5.100.10 + version: 5.104.3 '@tanstack/react-query': specifier: 'catalog:' - version: 5.100.10(react@19.2.3) + version: 5.104.3(react@19.2.3) '@tanstack/react-query-persist-client': specifier: 'catalog:' - version: 5.100.10(@tanstack/react-query@5.100.10(react@19.2.3))(react@19.2.3) + version: 5.104.3(@tanstack/react-query@5.104.3(react@19.2.3))(react@19.2.3) '@trpc/client': specifier: 'catalog:' version: 11.17.0(@trpc/server@11.17.0(typescript@7.0.2))(typescript@7.0.2) '@trpc/tanstack-react-query': specifier: 'catalog:' - version: 11.17.0(@tanstack/react-query@5.100.10(react@19.2.3))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@7.0.2))(typescript@7.0.2))(@trpc/server@11.17.0(typescript@7.0.2))(react@19.2.3)(typescript@7.0.2) + version: 11.17.0(@tanstack/react-query@5.104.3(react@19.2.3))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@7.0.2))(typescript@7.0.2))(@trpc/server@11.17.0(typescript@7.0.2))(react@19.2.3)(typescript@7.0.2) class-variance-authority: specifier: 0.7.1 version: 0.7.1 @@ -850,7 +850,7 @@ importers: version: 1.4.0 '@tanstack/react-query': specifier: 'catalog:' - version: 5.100.10(react@19.2.6) + version: 5.104.3(react@19.2.6) clsx: specifier: 2.1.1 version: 2.1.1 @@ -1163,7 +1163,7 @@ importers: version: 5.10.0 '@tanstack/react-query': specifier: 'catalog:' - version: 5.100.10(react@19.2.6) + version: 5.104.3(react@19.2.6) '@trpc/client': specifier: 'catalog:' version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) @@ -1172,7 +1172,7 @@ importers: version: 11.17.0(typescript@5.9.3) '@trpc/tanstack-react-query': specifier: 'catalog:' - version: 11.17.0(@tanstack/react-query@5.100.10(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) + version: 11.17.0(@tanstack/react-query@5.104.3(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) '@types/archiver': specifier: 7.0.0 version: 7.0.0 @@ -1763,7 +1763,7 @@ importers: devDependencies: '@tanstack/react-query': specifier: 'catalog:' - version: 5.100.10(react@19.2.6) + version: 5.104.3(react@19.2.6) '@types/react': specifier: 19.2.14 version: 19.2.14 @@ -10683,23 +10683,23 @@ packages: peerDependencies: vite: '>=8.0.16 <8.1.0' - '@tanstack/query-async-storage-persister@5.100.10': - resolution: {integrity: sha512-NbxsCI9qyMbEooFnFsAR2dbVQ6cmxZpOWSjLFy62qfMkxXnNjkskqex7YgtzWSaD/ozOOLgrbDiyYWEPYKmMyQ==} + '@tanstack/query-async-storage-persister@5.104.3': + resolution: {integrity: sha512-xunlTTS1NFNE5Uk0pEZMhriYMqdaiZVhqTSQmTfKzLHg+oDBM6tUhSQsdCwAC77mvGC5J59tGkwhFz8CHtvdsg==} - '@tanstack/query-core@5.100.10': - resolution: {integrity: sha512-8UR0yJR+GiQ40m3lPhUr0xbfAupe6GSQiksSBSa9SM2NjezFyxXCIA69/lz8cSoNKZLrw1/PktIyQBJcVeMi3w==} + '@tanstack/query-core@5.104.3': + resolution: {integrity: sha512-DZY9TuJAOgU3UyHUhXb4CcTYEHNZszlwkPg4VViIwTxOKzLprPUU+rbaPZQd3srqkGOtpaDdKpW972UV/LKlcg==} - '@tanstack/query-persist-client-core@5.100.10': - resolution: {integrity: sha512-O9Pey40DhTTDBABS0bHr+KNL5/VMf6PrqjexS8WoDDtnkaoWM+y0MSe0V9E5W+BwvkjM33mB3aYcCxa175gZTQ==} + '@tanstack/query-persist-client-core@5.104.3': + resolution: {integrity: sha512-6nhc/QbMpkKeuAM81SFSdcsJ9B8dm3fGHPODbau2cRSDyqcXiSl7sXQM7POVktch/YdgIGYPIQyZOQQaRarHMA==} - '@tanstack/react-query-persist-client@5.100.10': - resolution: {integrity: sha512-EImacngLXYEtzlrIPf8IAqKN3foS7cmSj4GWqsHJvc7K+8fy2c3s7mdV8oTJeii/TvrzO4X9fcnXi6tUHMIOHA==} + '@tanstack/react-query-persist-client@5.104.3': + resolution: {integrity: sha512-Dooa5cQ2Ter+9yHD3oD6vUzY+X4VEG9l9XkilX5OWFXMAtCEC+rSXwlfwYqNEMzAVigH7AcdubeRj2Vm+rCf8g==} peerDependencies: - '@tanstack/react-query': ^5.100.10 + '@tanstack/react-query': ^5.104.3 react: ^18 || ^19 - '@tanstack/react-query@5.100.10': - resolution: {integrity: sha512-FLaZf2RCrA/Zgp4aiu5tG3TyasTRO7aZ99skxQpr3Hg/zXOhu6yq5FZCYQ/tRaJtM9ylnoK8tFK7PolXQadv6Q==} + '@tanstack/react-query@5.104.3': + resolution: {integrity: sha512-5Ts1ImwJKqoJgPkLxl9WrPQy1JEoEmti3MaaODCfBamHUGFk57IFrc+AIksPq+BAm10EsroX56qm398Z42LG7w==} peerDependencies: react: ^18 || ^19 @@ -24447,11 +24447,11 @@ snapshots: '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) tslib: 2.8.1 - '@kilocode/kilo-chat-hooks@file:packages/kilo-chat-hooks(@tanstack/react-query@5.100.10(react@19.2.3))(react@19.2.3)': + '@kilocode/kilo-chat-hooks@file:packages/kilo-chat-hooks(@tanstack/react-query@5.104.3(react@19.2.3))(react@19.2.3)': dependencies: '@kilocode/event-service': link:packages/event-service '@kilocode/kilo-chat': link:packages/kilo-chat - '@tanstack/react-query': 5.100.10(react@19.2.3) + '@tanstack/react-query': 5.104.3(react@19.2.3) react: 19.2.3 '@kilocode/plugin@7.2.52': @@ -27560,7 +27560,7 @@ snapshots: '@sentry/conventions': 0.16.0 '@sentry/core': 10.69.0 - '@sentry/react-native@8.29.0(@babel/core@7.29.7)(@expo/config-types@57.0.2)(@expo/config@57.0.9(typescript@7.0.2))(@expo/env@2.4.3)(bufferutil@4.1.0)(dotenv@17.4.2)(expo-router@57.0.24)(expo@57.0.26)(metro-config@0.84.5)(metro-resolver@0.84.5)(open@11.0.0)(promise@8.3.0)(react-native@0.86.3(patch_hash=113932fc75a9e6f352c2a0668f6aa2be25e81326b7b96cc47f8420776a1a92f9)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(rollup@4.62.3)(typescript@7.0.2)(utf-8-validate@6.0.6)(webpack@5.105.4(esbuild@0.28.2))': + '@sentry/react-native@8.29.0(@babel/core@7.29.7)(@expo/config-types@57.0.2)(@expo/config@57.0.9(typescript@7.0.2))(@expo/env@2.4.3)(bufferutil@4.1.0)(dotenv@17.4.2)(expo-router@57.0.24)(expo@57.0.26)(metro-config@0.84.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(metro-resolver@0.84.5)(open@11.0.0)(promise@8.3.0)(react-native@0.86.3(patch_hash=113932fc75a9e6f352c2a0668f6aa2be25e81326b7b96cc47f8420776a1a92f9)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(rollup@4.62.3)(typescript@7.0.2)(utf-8-validate@6.0.6)(webpack@5.105.4(esbuild@0.28.2))': dependencies: '@expo/config-plugins': 57.0.9(typescript@7.0.2) '@sentry/browser': 10.75.2 @@ -28925,31 +28925,31 @@ snapshots: tailwindcss: 4.3.1 vite: 8.0.16(@types/node@24.12.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.4) - '@tanstack/query-async-storage-persister@5.100.10': + '@tanstack/query-async-storage-persister@5.104.3': dependencies: - '@tanstack/query-core': 5.100.10 - '@tanstack/query-persist-client-core': 5.100.10 + '@tanstack/query-core': 5.104.3 + '@tanstack/query-persist-client-core': 5.104.3 - '@tanstack/query-core@5.100.10': {} + '@tanstack/query-core@5.104.3': {} - '@tanstack/query-persist-client-core@5.100.10': + '@tanstack/query-persist-client-core@5.104.3': dependencies: - '@tanstack/query-core': 5.100.10 + '@tanstack/query-core': 5.104.3 - '@tanstack/react-query-persist-client@5.100.10(@tanstack/react-query@5.100.10(react@19.2.3))(react@19.2.3)': + '@tanstack/react-query-persist-client@5.104.3(@tanstack/react-query@5.104.3(react@19.2.3))(react@19.2.3)': dependencies: - '@tanstack/query-persist-client-core': 5.100.10 - '@tanstack/react-query': 5.100.10(react@19.2.3) + '@tanstack/query-persist-client-core': 5.104.3 + '@tanstack/react-query': 5.104.3(react@19.2.3) react: 19.2.3 - '@tanstack/react-query@5.100.10(react@19.2.3)': + '@tanstack/react-query@5.104.3(react@19.2.3)': dependencies: - '@tanstack/query-core': 5.100.10 + '@tanstack/query-core': 5.104.3 react: 19.2.3 - '@tanstack/react-query@5.100.10(react@19.2.6)': + '@tanstack/react-query@5.104.3(react@19.2.6)': dependencies: - '@tanstack/query-core': 5.100.10 + '@tanstack/query-core': 5.104.3 react: 19.2.6 '@tanstack/react-virtual@3.14.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': @@ -29021,17 +29021,17 @@ snapshots: dependencies: typescript: 7.0.2 - '@trpc/tanstack-react-query@11.17.0(@tanstack/react-query@5.100.10(react@19.2.3))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@7.0.2))(typescript@7.0.2))(@trpc/server@11.17.0(typescript@7.0.2))(react@19.2.3)(typescript@7.0.2)': + '@trpc/tanstack-react-query@11.17.0(@tanstack/react-query@5.104.3(react@19.2.3))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@7.0.2))(typescript@7.0.2))(@trpc/server@11.17.0(typescript@7.0.2))(react@19.2.3)(typescript@7.0.2)': dependencies: - '@tanstack/react-query': 5.100.10(react@19.2.3) + '@tanstack/react-query': 5.104.3(react@19.2.3) '@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@7.0.2))(typescript@7.0.2) '@trpc/server': 11.17.0(typescript@7.0.2) react: 19.2.3 typescript: 7.0.2 - '@trpc/tanstack-react-query@11.17.0(@tanstack/react-query@5.100.10(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3)': + '@trpc/tanstack-react-query@11.17.0(@tanstack/react-query@5.104.3(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3)': dependencies: - '@tanstack/react-query': 5.100.10(react@19.2.6) + '@tanstack/react-query': 5.104.3(react@19.2.6) '@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/server': 11.17.0(typescript@5.9.3) react: 19.2.6 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 76771e2a3e2..0da06a90a8c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -25,9 +25,9 @@ catalog: # mobile). Must NOT be added to `overrides`: the Sentry bundler plugins consume # @sentry/cli through its Node API, which v3 broke. See the note in `overrides`. '@sentry/cli': 3.6.2 - '@tanstack/query-async-storage-persister': 5.100.10 - '@tanstack/react-query': 5.100.10 - '@tanstack/react-query-persist-client': 5.100.10 + '@tanstack/query-async-storage-persister': 5.104.3 + '@tanstack/react-query': 5.104.3 + '@tanstack/react-query-persist-client': 5.104.3 '@trpc/client': 11.17.0 '@trpc/server': 11.17.0 '@trpc/tanstack-react-query': 11.17.0 From 5eac9c324aa13400037fbe7eab2c1040973075d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= <4062236+iscekic@users.noreply.github.com> Date: Tue, 20 Oct 2026 03:28:12 +0000 Subject: [PATCH 2/3] refactor(mobile): use the QueryClient query API The upgraded TanStack Query marks fetchQuery, prefetchQuery, ensureQueryData and Query.fetch as deprecated. Replace them with queryClient.query, keeping prefetch call sites non-throwing and expressing ensureQueryData as query with staleTime: 'static'. --- .../agents/agents-tab-badge.mounted.test.tsx | 2 +- .../security-agent/scope-entry-screen.test.ts | 8 ++++- .../components/todos/todo-lists-screen.tsx | 2 +- ...-sessions-live-sync.manual-refresh.test.ts | 2 +- .../active-sessions-live-sync.test-helpers.ts | 4 +-- .../src/lib/active-sessions-live-sync.ts | 2 +- apps/mobile/src/lib/agent-session-cache.ts | 12 ++++---- .../lib/credits/use-store-credit-products.ts | 2 +- .../use-agent-sessions.live.mounted.test.tsx | 2 +- ...-route-foreground-refresh.mounted.test.tsx | 4 +-- .../src/lib/hooks/use-security-agent.ts | 2 +- .../lib/hooks/use-session-mutations.test.ts | 4 +-- .../diff/use-pr-diff-context-loader.ts | 2 +- .../pr-review/use-check-github-connection.ts | 2 +- .../use-check-provider-connection.ts | 6 ++-- apps/mobile/src/lib/query-client.test.ts | 30 +++++++++---------- apps/mobile/src/lib/settings/bindings.ts | 3 +- apps/mobile/src/lib/settings/registry.test.ts | 2 +- apps/mobile/src/lib/startup-prefetch.ts | 2 +- .../src/lib/use-github-repos-refresh.ts | 2 +- .../src/lib/use-new-session-repos.test.ts | 10 +++---- apps/mobile/src/lib/use-new-session-repos.ts | 4 +-- 22 files changed, 59 insertions(+), 50 deletions(-) diff --git a/apps/mobile/src/components/agents/agents-tab-badge.mounted.test.tsx b/apps/mobile/src/components/agents/agents-tab-badge.mounted.test.tsx index d6ca3c3081a..e5ad58f50a6 100644 --- a/apps/mobile/src/components/agents/agents-tab-badge.mounted.test.tsx +++ b/apps/mobile/src/components/agents/agents-tab-badge.mounted.test.tsx @@ -94,7 +94,7 @@ describe('Agents needs-input badge and shared live count', () => { 'updates to %i from the shared cache while Home has focus', async count => { const queryClient = makeTestQueryClient(); - await queryClient.fetchQuery({ + await queryClient.query({ queryKey: key(), queryFn: makeQueryFn(), }); diff --git a/apps/mobile/src/components/security-agent/scope-entry-screen.test.ts b/apps/mobile/src/components/security-agent/scope-entry-screen.test.ts index 536461f86bc..9447aa03426 100644 --- a/apps/mobile/src/components/security-agent/scope-entry-screen.test.ts +++ b/apps/mobile/src/components/security-agent/scope-entry-screen.test.ts @@ -268,7 +268,13 @@ describe.each([ organizationId: 'org_123', }); const other = trpc.securityAgent.getConfig.queryOptions(); - void queryClient.prefetchQuery(other); + void (async () => { + try { + await queryClient.query(other); + } catch { + // Offline: the fetch stays paused for the retry path. + } + })(); queryClient.setQueryData(configKey, configData); const root = await mount('org_123', Screen); const error = host(root, 'PlatformErrorScreen')[0]; diff --git a/apps/mobile/src/components/todos/todo-lists-screen.tsx b/apps/mobile/src/components/todos/todo-lists-screen.tsx index 436c38f61a6..5367efa5fd4 100644 --- a/apps/mobile/src/components/todos/todo-lists-screen.tsx +++ b/apps/mobile/src/components/todos/todo-lists-screen.tsx @@ -85,7 +85,7 @@ export function TodoListsScreen({ segmentControl }: Readonly<{ segmentControl: R void (async () => { // The count covers finished to-dos too, which `openCount` leaves out. const items = await queryClient - .fetchQuery(trpc.todos.items.list.queryOptions({ listId: list.id })) + .query(trpc.todos.items.list.queryOptions({ listId: list.id })) .catch(() => null); const deleteList = () => { void Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); diff --git a/apps/mobile/src/lib/active-sessions-live-sync.manual-refresh.test.ts b/apps/mobile/src/lib/active-sessions-live-sync.manual-refresh.test.ts index 8c2f5583b39..c59f522152e 100644 --- a/apps/mobile/src/lib/active-sessions-live-sync.manual-refresh.test.ts +++ b/apps/mobile/src/lib/active-sessions-live-sync.manual-refresh.test.ts @@ -93,7 +93,7 @@ describe('ActiveSessionsLiveSync — manual refresh', () => { sync.attach(); let settled = false; - const fetchSpy = vi.spyOn(qc, 'fetchQuery'); + const fetchSpy = vi.spyOn(qc, 'query'); const pending = (async () => { const result = await refreshActiveSessionsNow(QUERY_KEY); settled = true; diff --git a/apps/mobile/src/lib/active-sessions-live-sync.test-helpers.ts b/apps/mobile/src/lib/active-sessions-live-sync.test-helpers.ts index 3404bae60f7..f1e832d3088 100644 --- a/apps/mobile/src/lib/active-sessions-live-sync.test-helpers.ts +++ b/apps/mobile/src/lib/active-sessions-live-sync.test-helpers.ts @@ -120,9 +120,9 @@ export function makeFakeQueryClient( const seed = qc.setQueryData.bind(qc); seed(QUERY_KEY, initial); let pendingFetch: Deferred | null = null; - const fetch = qc.fetchQuery.bind(qc); + const fetch = qc.query.bind(qc); const cancel = qc.cancelQueries.bind(qc); - const fetchSpy = vi.spyOn(qc, 'fetchQuery').mockImplementation(async options => { + const fetchSpy = vi.spyOn(qc, 'query').mockImplementation(async options => { const queryFn = options.queryFn; if (typeof queryFn !== 'function') { throw new TypeError('Expected a query function'); diff --git a/apps/mobile/src/lib/active-sessions-live-sync.ts b/apps/mobile/src/lib/active-sessions-live-sync.ts index bc821ced028..7c1d9b9ad11 100644 --- a/apps/mobile/src/lib/active-sessions-live-sync.ts +++ b/apps/mobile/src/lib/active-sessions-live-sync.ts @@ -285,7 +285,7 @@ export class ActiveSessionsLiveSync { try { await queryClient.cancelQueries({ queryKey, exact: true }); if (this.isCurrentAttachment(attachmentEpoch) && refresh.isCurrent()) { - const fetchPromise = queryClient.fetchQuery({ + const fetchPromise = queryClient.query({ queryKey, queryFn: fenceActiveSessionsQuery(queryFn, () => this.isCurrentAttachment(attachmentEpoch) diff --git a/apps/mobile/src/lib/agent-session-cache.ts b/apps/mobile/src/lib/agent-session-cache.ts index 447ee0b2c4e..29a9e3e859f 100644 --- a/apps/mobile/src/lib/agent-session-cache.ts +++ b/apps/mobile/src/lib/agent-session-cache.ts @@ -51,11 +51,13 @@ export const SESSION_TRANSCRIPT_STALE_TIME_MS = 60_000; * fetching on the critical path. */ export async function prefetchSessionTranscript( - queryClient: Pick, + queryClient: Pick, options: { queryKey: readonly unknown[] } ): Promise { - await queryClient.prefetchQuery({ - ...options, - staleTime: SESSION_TRANSCRIPT_STALE_TIME_MS, - }); + await queryClient + .query({ + ...options, + staleTime: SESSION_TRANSCRIPT_STALE_TIME_MS, + }) + .catch(() => undefined); } diff --git a/apps/mobile/src/lib/credits/use-store-credit-products.ts b/apps/mobile/src/lib/credits/use-store-credit-products.ts index 171dce65a04..a76352a0290 100644 --- a/apps/mobile/src/lib/credits/use-store-credit-products.ts +++ b/apps/mobile/src/lib/credits/use-store-credit-products.ts @@ -91,7 +91,7 @@ export function useStoreCreditProducts(options: StoreCreditProductsOptions) { const loadedProducts = await loadStoreCreditProducts({ fetchStoreProducts: options.fetchStoreProducts, loadBackendProducts: async () => { - const backendResponse = await queryClient.fetchQuery( + const backendResponse = await queryClient.query( trpc.credits.getMobileStoreProducts.queryOptions() ); return backendResponse; diff --git a/apps/mobile/src/lib/hooks/use-agent-sessions.live.mounted.test.tsx b/apps/mobile/src/lib/hooks/use-agent-sessions.live.mounted.test.tsx index 000b9eae5d2..76c16e089b4 100644 --- a/apps/mobile/src/lib/hooks/use-agent-sessions.live.mounted.test.tsx +++ b/apps/mobile/src/lib/hooks/use-agent-sessions.live.mounted.test.tsx @@ -250,7 +250,7 @@ describe('live query presentation and refresh contracts', () => { it.each(['cancel', 'sign-out'])( 'rejects a fallback result after %s without publishing late data', async boundary => { - await client.fetchQuery({ queryKey: QUERY_KEY, queryFn: () => cached }); + await client.query({ queryKey: QUERY_KEY, queryFn: () => cached }); await render(); const network = deferred(); state.request.mockReturnValue(network.promise); diff --git a/apps/mobile/src/lib/hooks/use-route-foreground-refresh.mounted.test.tsx b/apps/mobile/src/lib/hooks/use-route-foreground-refresh.mounted.test.tsx index 1be0a554d27..930b6a9ecc4 100644 --- a/apps/mobile/src/lib/hooks/use-route-foreground-refresh.mounted.test.tsx +++ b/apps/mobile/src/lib/hooks/use-route-foreground-refresh.mounted.test.tsx @@ -234,7 +234,7 @@ describe('useRouteForegroundRefresh key matching with a real QueryClient', () => it('invalidates a tRPC-shaped query key with the nested prefix form', async () => { const queryClient = new QueryClient(); const queryFn = vi.fn().mockResolvedValue('sentinel'); - await queryClient.prefetchQuery({ queryKey: [['user', 'getMe']], queryFn }); + await queryClient.query({ queryKey: [['user', 'getMe']], queryFn }); await renderProbeWithProvider(queryClient, [[['user']]]); @@ -246,7 +246,7 @@ describe('useRouteForegroundRefresh key matching with a real QueryClient', () => it('does not invalidate a tRPC-shaped query key with the flat prefix form', async () => { const queryClient = new QueryClient(); const queryFn = vi.fn().mockResolvedValue('sentinel'); - await queryClient.prefetchQuery({ queryKey: [['user', 'getMe']], queryFn }); + await queryClient.query({ queryKey: [['user', 'getMe']], queryFn }); await renderProbeWithProvider(queryClient, [['user']]); diff --git a/apps/mobile/src/lib/hooks/use-security-agent.ts b/apps/mobile/src/lib/hooks/use-security-agent.ts index 00d1b2fbe40..0c6e9373bbd 100644 --- a/apps/mobile/src/lib/hooks/use-security-agent.ts +++ b/apps/mobile/src/lib/hooks/use-security-agent.ts @@ -99,7 +99,7 @@ export function useRetrySecurityAgentSettings(scope: string) { // Cancel first, then bypass NetInfo for this deliberate attempt only. await queryClient.cancelQueries({ queryKey, exact: true }); try { - await queryClient.fetchQuery({ + await queryClient.query({ ...options, queryKey, networkMode: 'always', diff --git a/apps/mobile/src/lib/hooks/use-session-mutations.test.ts b/apps/mobile/src/lib/hooks/use-session-mutations.test.ts index 961b3e235f2..24b015b7117 100644 --- a/apps/mobile/src/lib/hooks/use-session-mutations.test.ts +++ b/apps/mobile/src/lib/hooks/use-session-mutations.test.ts @@ -116,12 +116,12 @@ describe('useSessionMutations account publication', () => { it('retitles and rolls back both caches without accepting manual writes or clearing a fetch failure', async () => { const query = client.getQueryCache().find({ queryKey: QUERY_KEY, exact: true }); - await client.fetchQuery({ + await client.query({ queryKey: QUERY_KEY, queryFn: () => ({ sessions: [makeCached({ id: 's1', title: 'Old' })] }), }); await expect( - client.fetchQuery({ + client.query({ queryKey: QUERY_KEY, queryFn: () => { throw new Error('offline'); diff --git a/apps/mobile/src/lib/pr-review/diff/use-pr-diff-context-loader.ts b/apps/mobile/src/lib/pr-review/diff/use-pr-diff-context-loader.ts index 44dc81cf0ec..74e14a0a458 100644 --- a/apps/mobile/src/lib/pr-review/diff/use-pr-diff-context-loader.ts +++ b/apps/mobile/src/lib/pr-review/diff/use-pr-diff-context-loader.ts @@ -109,7 +109,7 @@ export function usePrDiffContextLoader(args: { const target = contextScopeForItem(scope, item.ref, { owner, repo, headSha }); void (async () => { try { - const result = await queryClient.fetchQuery( + const result = await queryClient.query( buildPrFileLinesQueryOptions(trpc, target.scope, { ref: target.ref, path: item.filePath, diff --git a/apps/mobile/src/lib/pr-review/use-check-github-connection.ts b/apps/mobile/src/lib/pr-review/use-check-github-connection.ts index cb75b26d088..80431c5d42b 100644 --- a/apps/mobile/src/lib/pr-review/use-check-github-connection.ts +++ b/apps/mobile/src/lib/pr-review/use-check-github-connection.ts @@ -9,7 +9,7 @@ export function useCheckGitHubConnection() { return useMutation({ mutationFn: async () => { - const authorization = await queryClient.fetchQuery({ + const authorization = await queryClient.query({ ...trpc.githubApps.getUserAuthorization.queryOptions(), staleTime: 0, }); diff --git a/apps/mobile/src/lib/pr-review/use-check-provider-connection.ts b/apps/mobile/src/lib/pr-review/use-check-provider-connection.ts index 38c0460b467..2daf6efe318 100644 --- a/apps/mobile/src/lib/pr-review/use-check-provider-connection.ts +++ b/apps/mobile/src/lib/pr-review/use-check-provider-connection.ts @@ -37,10 +37,10 @@ export function useCheckProviderConnection() { } // The two providers answer with different status shapes, so each arm // fetches its own options — a union of the two queryOptions types is - // not assignable to a single fetchQuery call. + // not assignable to a single query call. const status = input.platform === 'gitlab' - ? await queryClient.fetchQuery({ + ? await queryClient.query({ ...(input.organizationId ? trpc.organizations.reviewAgent.getGitLabStatus.queryOptions({ organizationId: input.organizationId, @@ -48,7 +48,7 @@ export function useCheckProviderConnection() { : trpc.personalReviewAgent.getGitLabStatus.queryOptions()), staleTime: 0, }) - : await queryClient.fetchQuery({ + : await queryClient.query({ ...trpc.organizations.reviewAgent.getBitbucketReadiness.queryOptions({ organizationId: input.organizationId ?? '', }), diff --git a/apps/mobile/src/lib/query-client.test.ts b/apps/mobile/src/lib/query-client.test.ts index c59d539f4a7..43834625198 100644 --- a/apps/mobile/src/lib/query-client.test.ts +++ b/apps/mobile/src/lib/query-client.test.ts @@ -53,7 +53,7 @@ describe('query retry policy', () => { let attempts = 0; await expect( - queryClient.fetchQuery({ + queryClient.query({ queryKey: ['session', 'retry-policy', code], retryDelay: 0, queryFn: () => { @@ -90,7 +90,7 @@ describe('permission-denied query removal', () => { }); await expect( - queryClient.fetchQuery({ + queryClient.query({ queryKey: org1Key, staleTime: 0, queryFn: () => { @@ -123,7 +123,7 @@ describe('permission-denied query removal', () => { }); await expect( - queryClient.fetchQuery({ + queryClient.query({ queryKey: key, staleTime: 0, queryFn: () => { @@ -188,7 +188,7 @@ describe('permission-denied query removal', () => { }); await expect( - queryClient.fetchQuery({ + queryClient.query({ queryKey: key, staleTime: 0, queryFn: () => { @@ -214,7 +214,7 @@ describe('accepted active-session outcomes', () => { const query = client.getQueryCache().find({ queryKey: QUERY_KEY, exact: true }); query?.setState({ status: 'success', dataUpdatedAt: Date.now() - 1 }); expect(getActiveSessionsQueryMetadata(query)).toBe(absent); - await client.fetchQuery({ queryKey: QUERY_KEY, queryFn: () => emptyResult, staleTime: 0 }); + await client.query({ queryKey: QUERY_KEY, queryFn: () => emptyResult, staleTime: 0 }); const accepted = getActiveSessionsQueryMetadata(query); expect(accepted.acceptedRevision).toBe(1); client.setQueryData(QUERY_KEY, emptyResult); @@ -250,7 +250,7 @@ describe('accepted active-session outcomes', () => { expect(failed.acceptedRevision).toBe(0); client.setQueryData(QUERY_KEY, { sessions: [{ id: 'live', title: 'socket' }] }); const recovery = deferred(); - const retry = client.fetchQuery({ + const retry = client.query({ queryKey: QUERY_KEY, queryFn: async () => { const result = await recovery.promise; @@ -262,7 +262,7 @@ describe('accepted active-session outcomes', () => { await retry; expect(getActiveSessionsQueryMetadata(query)).toBe(failed); recovery.resolve(emptyResult); - await client.fetchQuery({ queryKey: QUERY_KEY, queryFn: () => emptyResult }); + await client.query({ queryKey: QUERY_KEY, queryFn: () => emptyResult }); expect(getActiveSessionsQueryMetadata(query)).toEqual({ acceptedRevision: 1, terminalError: null, @@ -275,7 +275,7 @@ describe('accepted active-session outcomes', () => { const client = makeClient(); const result = deferred(); let attempts = 0; - const pending = client.fetchQuery({ + const pending = client.query({ queryKey: QUERY_KEY, retry: 1, retryDelay: 0, @@ -302,7 +302,7 @@ describe('accepted active-session outcomes', () => { 'preserves provenance across remounts but resets it after %s', async removal => { const client = makeClient(); - await client.fetchQuery({ queryKey: QUERY_KEY, queryFn: () => emptyResult }); + await client.query({ queryKey: QUERY_KEY, queryFn: () => emptyResult }); const query = client.getQueryCache().find({ queryKey: QUERY_KEY, exact: true }); const accepted = getActiveSessionsQueryMetadata(query); const observer = new QueryObserver(client, { queryKey: QUERY_KEY, staleTime: Infinity }); @@ -325,7 +325,7 @@ describe('accepted active-session outcomes', () => { const recreated = client.getQueryCache().find({ queryKey: QUERY_KEY, exact: true }); expect(recreated).not.toBe(query); expect(getActiveSessionsQueryMetadata(recreated).acceptedRevision).toBe(0); - await client.fetchQuery({ queryKey: QUERY_KEY, queryFn: () => emptyResult }); + await client.query({ queryKey: QUERY_KEY, queryFn: () => emptyResult }); expect(getActiveSessionsQueryMetadata(recreated).acceptedRevision).toBe(1); expect(published).toEqual([0]); } @@ -352,17 +352,17 @@ describe('accepted active-session outcomes', () => { subscribeActiveSessionsQueryMetadata(otherQuery, () => { otherPublished.push(getActiveSessionsQueryMetadata(otherQuery).acceptedRevision); }); - await client.fetchQuery({ queryKey: otherKey, queryFn: () => emptyResult }); + await client.query({ queryKey: otherKey, queryFn: () => emptyResult }); expect( getActiveSessionsQueryMetadata(client.getQueryCache().find({ queryKey: otherKey })) .acceptedRevision ).toBe(0); expect(published).toEqual([]); - await client.fetchQuery({ queryKey: QUERY_KEY, queryFn: () => emptyResult }); + await client.query({ queryKey: QUERY_KEY, queryFn: () => emptyResult }); expect(published).toEqual([1]); client.setQueryData(QUERY_KEY, emptyResult); expect(published).toEqual([1]); - await client.fetchQuery({ queryKey: QUERY_KEY, queryFn: () => emptyResult }); + await client.query({ queryKey: QUERY_KEY, queryFn: () => emptyResult }); expect(published).toEqual([1, 2]); expect(otherPublished).toEqual([]); expect(getActiveSessionsQueryMetadata(otherQuery).acceptedRevision).toBe(0); @@ -383,7 +383,7 @@ describe('app error reporting', () => { const generic = new Error('generic query failure'); await expect( - queryClient.fetchQuery({ + queryClient.query({ queryKey: ['session', 'generic'], queryFn: () => { throw generic; @@ -404,7 +404,7 @@ describe('app error reporting', () => { data: { code: 'INTERNAL_SERVER_ERROR' }, }); await expect( - queryClient.fetchQuery({ + queryClient.query({ queryKey: ['session', 'trpc'], queryFn: () => { throw trpcError; diff --git a/apps/mobile/src/lib/settings/bindings.ts b/apps/mobile/src/lib/settings/bindings.ts index a1b103443ef..12c62e5feb4 100644 --- a/apps/mobile/src/lib/settings/bindings.ts +++ b/apps/mobile/src/lib/settings/bindings.ts @@ -29,12 +29,13 @@ export const NOTIFICATION_PREFERENCES_QUERY_KEY = [ export function readNotificationPreferences(): Effect.Effect { return Effect.tryPromise({ try: async () => { - const preferences = await queryClient.ensureQueryData({ + const preferences = await queryClient.query({ queryKey: NOTIFICATION_PREFERENCES_QUERY_KEY, queryFn: async () => { const result = await trpcClient.user.getNotificationPreferences.query(); return result; }, + staleTime: 'static', }); return preferences; }, diff --git a/apps/mobile/src/lib/settings/registry.test.ts b/apps/mobile/src/lib/settings/registry.test.ts index 7290c983ee7..d999d11cc14 100644 --- a/apps/mobile/src/lib/settings/registry.test.ts +++ b/apps/mobile/src/lib/settings/registry.test.ts @@ -62,7 +62,7 @@ vi.mock('@/lib/trpc', () => ({ const queryClientMock = vi.hoisted(() => ({ getQueryData: vi.fn(), - ensureQueryData: vi.fn(async ({ queryFn }: { queryFn: () => Promise }) => { + query: vi.fn(async ({ queryFn }: { queryFn: () => Promise }) => { const result = await queryFn(); return result; }), diff --git a/apps/mobile/src/lib/startup-prefetch.ts b/apps/mobile/src/lib/startup-prefetch.ts index 4ce65633a18..4387556c510 100644 --- a/apps/mobile/src/lib/startup-prefetch.ts +++ b/apps/mobile/src/lib/startup-prefetch.ts @@ -21,7 +21,7 @@ export function prefetchCurrentUser(): void { try { const token = await preloadedAuthToken; if (token != null) { - await queryClient.prefetchQuery(trpcOptions.user.getMe.queryOptions()); + await queryClient.query(trpcOptions.user.getMe.queryOptions()).catch(() => undefined); } } catch { // A rejected preload (keychain unavailable at process start) must not diff --git a/apps/mobile/src/lib/use-github-repos-refresh.ts b/apps/mobile/src/lib/use-github-repos-refresh.ts index 7e757c6f892..648afe9208c 100644 --- a/apps/mobile/src/lib/use-github-repos-refresh.ts +++ b/apps/mobile/src/lib/use-github-repos-refresh.ts @@ -47,7 +47,7 @@ export function useGitHubReposRefresh({ async (isReturnTriggered: boolean) => { setIsRefreshingRepos(true); try { - const fresh = await queryClient.fetchQuery({ + const fresh = await queryClient.query({ ...(organizationId ? trpc.organizations.cloudAgentNext.listGitHubRepositories.queryOptions({ organizationId, diff --git a/apps/mobile/src/lib/use-new-session-repos.test.ts b/apps/mobile/src/lib/use-new-session-repos.test.ts index 3927eb62659..c3c41e0ac22 100644 --- a/apps/mobile/src/lib/use-new-session-repos.test.ts +++ b/apps/mobile/src/lib/use-new-session-repos.test.ts @@ -12,7 +12,7 @@ import { import { useNewSessionRepos, useRepositoryBranches } from './use-new-session-repos'; const mocks = vi.hoisted(() => ({ - fetchQuery: vi.fn(async (_opts: unknown): Promise => ({})), + query: vi.fn(async (_opts: unknown): Promise => ({})), setQueryData: vi.fn(() => undefined), toastError: vi.fn(), refreshGitHubForceFresh: vi.fn(async () => undefined), @@ -59,7 +59,7 @@ vi.mock('@tanstack/react-query', () => ({ }; return options.queryFn ? { ...base, ...mocks.branchQueryResult } : base; }, - useQueryClient: () => ({ fetchQuery: mocks.fetchQuery, setQueryData: mocks.setQueryData }), + useQueryClient: () => ({ query: mocks.query, setQueryData: mocks.setQueryData }), })); vi.mock('@/lib/config', () => ({ WEB_BASE_URL: 'https://app.example.com' })); @@ -181,11 +181,11 @@ function requireResult(resultRef: { current: ReposResult | null }): ReposResult return result; } -// Every provider's force-fresh reads `fetchQuery` with a `queryKey` whose first +// Every provider's force-fresh reads `query` with a `queryKey` whose first // element names the provider, so the fake can answer Bitbucket and GitLab // differently from one call site. function mockFetchQuery(resultForBitbucket: unknown, gitlabAndGithub: unknown) { - mocks.fetchQuery.mockImplementation(async (opts: unknown) => { + mocks.query.mockImplementation(async (opts: unknown) => { const queryKey = (opts as { queryKey?: unknown[] }).queryKey; return Array.isArray(queryKey) && queryKey[0] === 'bitbucket' ? resultForBitbucket @@ -195,7 +195,7 @@ function mockFetchQuery(resultForBitbucket: unknown, gitlabAndGithub: unknown) { beforeEach(() => { vi.clearAllMocks(); - mocks.fetchQuery.mockImplementation(async (_opts: unknown) => ({ repositories: [] })); + mocks.query.mockImplementation(async (_opts: unknown) => ({ repositories: [] })); mocks.queryCalls.length = 0; mocks.branchQueryResult = {}; }); diff --git a/apps/mobile/src/lib/use-new-session-repos.ts b/apps/mobile/src/lib/use-new-session-repos.ts index 0dd6fe165b3..55ceca89a06 100644 --- a/apps/mobile/src/lib/use-new-session-repos.ts +++ b/apps/mobile/src/lib/use-new-session-repos.ts @@ -242,7 +242,7 @@ export function useNewSessionRepos({ const [isRefreshingProviders, setIsRefreshingProviders] = useState(false); const forceFreshGitLab = useCallback(async () => { - const fresh = await queryClient.fetchQuery({ + const fresh = await queryClient.query({ ...(organizationId ? trpc.organizations.cloudAgentNext.listGitLabRepositories.queryOptions({ organizationId, @@ -270,7 +270,7 @@ export function useNewSessionRepos({ if (!organizationId) { return; } - const fresh = await queryClient.fetchQuery({ + const fresh = await queryClient.query({ ...trpc.organizations.cloudAgentNext.listBitbucketRepositories.queryOptions({ organizationId, forceRefresh: true, From 55ac5e899515bffd3ad4f7e24e4502a88c0c6e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= <4062236+iscekic@users.noreply.github.com> Date: Tue, 20 Oct 2026 04:30:49 +0000 Subject: [PATCH 3/3] chore(mobile): request review of the catalog bump