From 16b7b37de9085eea9bfc9a5bae306150afbc20bc Mon Sep 17 00:00:00 2001 From: Raashish Aggarwal <94279692+raashish1601@users.noreply.github.com> Date: Sun, 24 May 2026 22:48:17 +0530 Subject: [PATCH 1/3] fix(solid-query): track resource result fields --- .../src/__tests__/useQuery.test.tsx | 67 +++++++++++++++++++ packages/solid-query/src/useBaseQuery.ts | 32 +++++++++ 2 files changed, 99 insertions(+) diff --git a/packages/solid-query/src/__tests__/useQuery.test.tsx b/packages/solid-query/src/__tests__/useQuery.test.tsx index 745a9ab1cc2..cec4d3a4a5e 100644 --- a/packages/solid-query/src/__tests__/useQuery.test.tsx +++ b/packages/solid-query/src/__tests__/useQuery.test.tsx @@ -30,6 +30,7 @@ import { QueryClient, QueryClientProvider, keepPreviousData, + queryOptions, useQuery, } from '..' import { Blink, mockOnlineManagerIsOnline, setActTimeout } from './utils' @@ -244,6 +245,72 @@ describe('useQuery', () => { expect(rendered.getByText('test')).toBeInTheDocument() }) + it('should fetch when a curried queryOptions result only reads status fields', async () => { + const key = queryKey() + const queryFn = vi.fn((slug: string) => `test-${slug}`) + const fetchQueryOptions = (slug: string) => + queryOptions({ + queryKey: [key, slug], + queryFn: () => queryFn(slug), + }) + + function Page() { + const options = fetchQueryOptions('slug') + const state = useQuery(() => options) + + return ( + + pending + error + success + + ) + } + + const rendered = render(() => ( + + + + )) + + expect(rendered.getByText('pending')).toBeInTheDocument() + await vi.advanceTimersByTimeAsync(10) + expect(queryFn).toHaveBeenCalledTimes(1) + expect(rendered.getByText('success')).toBeInTheDocument() + }) + + it('should fetch when a curried queryOptions result only reads resource fields', async () => { + const key = queryKey() + const queryFn = vi.fn((slug: string) => `test-${slug}`) + const fetchQueryOptions = (slug: string) => + queryOptions({ + queryKey: [key, slug], + queryFn: () => queryFn(slug), + }) + + function Page() { + const options = fetchQueryOptions('slug') + const state = useQuery(() => options) + + void state.error + void state.failureReason + void state.refetch + void state.promise + + return
mounted
+ } + + const rendered = render(() => ( + + + + )) + + expect(rendered.getByText('mounted')).toBeInTheDocument() + await vi.advanceTimersByTimeAsync(10) + expect(queryFn).toHaveBeenCalledTimes(1) + }) + it('should return the correct states for a successful query', async () => { const key = queryKey() const states: Array> = [] diff --git a/packages/solid-query/src/useBaseQuery.ts b/packages/solid-query/src/useBaseQuery.ts index 773d0719e0c..97b665631e0 100644 --- a/packages/solid-query/src/useBaseQuery.ts +++ b/packages/solid-query/src/useBaseQuery.ts @@ -99,6 +99,33 @@ const hydratableObserverResult = < return obj } +const resourceTrackingProps = new Set([ + 'dataUpdatedAt', + 'error', + 'errorUpdatedAt', + 'failureCount', + 'failureReason', + 'errorUpdateCount', + 'isError', + 'isFetched', + 'isFetchedAfterMount', + 'isFetching', + 'isLoading', + 'isPending', + 'isLoadingError', + 'isInitialLoading', + 'isPaused', + 'isPlaceholderData', + 'isRefetchError', + 'isRefetching', + 'isStale', + 'isSuccess', + 'isEnabled', + 'refetch', + 'promise', + 'status', + 'fetchStatus', +]) // Base Query Function that is used to create the query. export function useBaseQuery< TQueryFnData, @@ -381,6 +408,11 @@ export function useBaseQuery< } return queryResource()?.data } + if (resourceTrackingProps.has(prop)) { + // Solid resources are lazy, so status-only consumers still need to read + // the resource once to start the observer subscription and fetch. + queryResource() + } return Reflect.get(target, prop) }, } From 60e16bfbc6d9f52504f2d04071c8cb01766ef490 Mon Sep 17 00:00:00 2001 From: Raashish Aggarwal <94279692+raashish1601@users.noreply.github.com> Date: Sun, 24 May 2026 15:26:23 +0530 Subject: [PATCH 2/3] fix(solid-query): fetch on status-only reads --- .changeset/solid-query-status-resource.md | 5 +++++ packages/solid-query/src/__tests__/useQuery.test.tsx | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .changeset/solid-query-status-resource.md diff --git a/.changeset/solid-query-status-resource.md b/.changeset/solid-query-status-resource.md new file mode 100644 index 00000000000..12a340a386f --- /dev/null +++ b/.changeset/solid-query-status-resource.md @@ -0,0 +1,5 @@ +--- +"@tanstack/solid-query": patch +--- + +Start Solid query resources when status fields are read so curried `queryOptions` fetch on mount without requiring `data` access. diff --git a/packages/solid-query/src/__tests__/useQuery.test.tsx b/packages/solid-query/src/__tests__/useQuery.test.tsx index cec4d3a4a5e..44b0346a403 100644 --- a/packages/solid-query/src/__tests__/useQuery.test.tsx +++ b/packages/solid-query/src/__tests__/useQuery.test.tsx @@ -310,7 +310,6 @@ describe('useQuery', () => { await vi.advanceTimersByTimeAsync(10) expect(queryFn).toHaveBeenCalledTimes(1) }) - it('should return the correct states for a successful query', async () => { const key = queryKey() const states: Array> = [] From c0529d2433426f1c95cfc4929d1673ed093853fc Mon Sep 17 00:00:00 2001 From: Raashish Aggarwal <94279692+raashish1601@users.noreply.github.com> Date: Sat, 30 May 2026 17:11:07 +0530 Subject: [PATCH 3/3] fix(query-devtools): sync style nonce with goober --- packages/query-devtools/src/__tests__/utils.test.ts | 9 +++++++++ packages/query-devtools/src/utils.tsx | 1 + 2 files changed, 10 insertions(+) diff --git a/packages/query-devtools/src/__tests__/utils.test.ts b/packages/query-devtools/src/__tests__/utils.test.ts index 511553e2bb8..f59199f3869 100644 --- a/packages/query-devtools/src/__tests__/utils.test.ts +++ b/packages/query-devtools/src/__tests__/utils.test.ts @@ -982,6 +982,7 @@ describe('Utils tests', () => { describe('setupStyleSheet', () => { afterEach(() => { document.head.querySelector('#_goober')?.remove() + delete (window as Window & { __nonce__?: string }).__nonce__ }) it('should not insert any style tag when "nonce" is missing', () => { @@ -1004,6 +1005,14 @@ describe('Utils tests', () => { expect(styleTag?.tagName).toBe('STYLE') }) + it('should set "window.__nonce__" from the provided nonce', () => { + setupStyleSheet('test-nonce') + + expect( + (window as Window & { __nonce__?: string }).__nonce__, + ).toBe('test-nonce') + }) + it('should set the "nonce" attribute on the inserted style tag', () => { setupStyleSheet('test-nonce') diff --git a/packages/query-devtools/src/utils.tsx b/packages/query-devtools/src/utils.tsx index 5306f2cf5f2..b09a2455d19 100644 --- a/packages/query-devtools/src/utils.tsx +++ b/packages/query-devtools/src/utils.tsx @@ -306,6 +306,7 @@ export const deleteNestedDataByPath = ( // Adds a nonce to the style tag if needed export const setupStyleSheet = (nonce?: string, target?: ShadowRoot) => { if (!nonce) return + ;(window as Window & { __nonce__?: string }).__nonce__ = nonce const styleExists = document.querySelector('#_goober') || target?.querySelector('#_goober')