Skip to content

refactor(solid-query): move off sharedConfig onto Solid's public hydration API - #11751

Merged
brenelz merged 4 commits into
TanStack:solid-query-v6-prefrom
ryansolid:solid-query-public-hydration-api
Sep 30, 2026
Merged

brenelz merged 4 commits into
TanStack:solid-query-v6-prefrom
ryansolid:solid-query-public-hydration-api

Conversation

@ryansolid

@ryansolid ryansolid commented Sep 30, 2026 •

Copy link
Copy Markdown

What

Moves @tanstack/solid-query (and solid-query-devtools) off Solid's internal sharedConfig onto Solid 2.0's public hydration API, released in solid-js / @solidjs/web 2.0.0-rc.13:

// solid-js
isHydrating(): boolean   // claim-window aware; false on the server
isHydratable(): boolean  // false under <NoHydration>, true again inside <Hydration>
// @solidjs/web
getHydrationWriter(): HydrationWriter | undefined                 // server
takeHydrationValue<T>(key: string): HydrationValue<T> | undefined // client; reads and removes the entry

Why

In the Solid 2.0 RC, sharedConfig is @internal and stripped from the published solid-js declarations, so the adapter fails to type-check (TS2305 at QueryClientProvider.tsx, cacheAggregate.ts, useBaseQuery.ts). The runtime reads also depended on undocumented shapes: context.serialize, context.noHydrate, the s/v stamps on serialized promises, and deleting from _$HY.r by hand. The public API owns those details now.

Core PR: solidjs/solid#3718

Changes by file

  • solid-query/src/QueryClientProvider.tsx (serializeCacheOnServer): the cast sharedConfig.context → getHydrationWriter(). The !ctx.async || ctx.noHydrate guard → !writer.async || !isHydratable(), so <NoHydration> is still respected; library writes are not gated by Solid itself. ctx.serialize(key, v) → writer.write(key, v). It's still called synchronously in provider setup, so the owner is known, and cache-event writes reuse the captured writer.
  • solid-query/src/useBaseQuery.ts:
    • hydratedMount and the in-pass NEVER guard: !isServer && sharedConfig.hydrating → isHydrating().
    • The streamed entry: sharedConfig.has/load + stamp decoding + delete _$HY.r[key] → takeHydrationValue(key), matching on status. resolved → settle with the value; rejected → settle empty; pending → settle on the promise's outcome; no entry on a hydrated mount → prime and attach, as before.
    • The dataStore doc comment now describes snapshot hydration (see the test change below).
  • solid-query/src/cacheAggregate.ts: hydratedMount → isHydrating().
  • solid-query-devtools/src/clientOnly.tsx: sharedConfig.hydrating → isHydrating().
  • solid-query/src/__tests__/hydration.test.tsx: one test updated (see below).
  • package.jsons + pnpm-lock.yaml: Solid rc.13 (see Dependencies).
  • .changeset/solid-query-public-hydration-api.md: patch for @tanstack/solid-query, @tanstack/solid-query-devtools and @tanstack/solid-query-persist-client, including the new peer floor.

No sharedConfig or solid-js/internal import remains in the Solid packages.

Test change: open-stream cache writes

cache writes during the open stream commit when hydration completes is now cache writes during the open stream commit immediately outside pending boundaries.

The old test pinned behavior that contradicts the design of Solid's snapshot hydration. Snapshot hydration exists so that everything outside an incomplete boundary hydrates and moves on normally. Nested boundaries that are still streaming hydrate against the server snapshot, so they don't fail hydration. The test instead required a boundary that had already resumed (#header) to keep showing the server value until the whole stream closed. That wait defeats the point of snapshot hydration. rc.13 makes nodes outside still-pending streamed boundaries recompute on client writes.

With the feed boundary still streaming, the test now expects:

  • setQueryData(['header'], …) reaches the cache and #header's DOM immediately.
  • A mid-stream invalidateQueries refetches at once and its result (header-client) commits as it lands.
  • #feed stays on its fallback throughout. When its chunk arrives, it hydrates from the server payload (feed-server) without a refetch, and #header keeps its client state.
  • The final "fully live" check is unchanged.

There are no adapter runtime changes for this.

Dependencies

  • solid-js, @solidjs/web, @solidjs/signals, @solidjs/babel-plugin: ^2.0.0-rc.9 → ^2.0.0-rc.13 in solid-query, solid-query-devtools, solid-query-persist-client, the Solid examples and integrations/solid-vite.
  • Peer floors: solid-js (all three packages) and @solidjs/web (solid-query) go from >=2.0.0-rc.9 <3.0.0 to >=2.0.0-rc.13 <3.0.0. rc.13 is the first release with the APIs the adapter now imports. @solidjs/web was already a peer of solid-query, so no peer dependency is added.
  • @solidjs/vite-plugin: ^3.0.0-next.44 → ^3.0.0-next.46, so the compiler it loads is rc.13 as well. next.44 passes a componentNames option that @solidjs/compiler rc.13 rejects. Holding the compiler at rc.9 would compile against a different runtime than the one installed, which is the mismatch fix(solid-query): follow Solid 2.0.0-rc.9 #11543 fixed.
  • Lockfile: compared with a plain pnpm install, only the Solid packages above changed. @emnapi/* dropped out with the rc.9 compiler's wasm binary.

Validation

Against the published rc.13 packages (a plain pnpm install, no local links):

  • @tanstack/solid-query: 366 passed / 1 skipped (the pre-existing skip), including the renamed hydration test. The vitest typecheck reports no errors. test:types (TS 5.8, 5.9, 6.0, tsc --build), test:eslint, test:build and build pass.
  • @tanstack/solid-query-devtools: 33 passed. test:types, test:eslint, test:build and build pass.
  • @tanstack/solid-query-persist-client: 7 passed. test:types, test:eslint, test:build and build pass.
  • test:sherif and test:knip pass. vite build succeeds for integrations/solid-vite and the basic, simple, offline, basic-graphql-request and default-query-function Solid examples.

The migration was also run before release against local core builds of solidjs/solid#3718, with the same 366 / 1.

— Claude via Cursor, on behalf of @ryansolid

…ation API

sharedConfig is @internal in Solid 2.0 and stripped from the published
solid-js declarations, so the adapter's imports fail with TS2305. Use the
public API instead:

- isHydrating() for the hydrating-mount checks (useBaseQuery,
  cacheAggregate, devtools clientOnly)
- getHydrationWriter() + isHydratable() for the provider's server cache
  stream (respects <NoHydration> as ctx.noHydrate did)
- takeHydrationValue() for useQuery's streamed entry, replacing
  sharedConfig.has/load, the s/v stamp decoding and the manual _$HY.r
  delete

Requires solid-js / @solidjs/web 2.0.0-rc.13; the dependency bump
follows once it is published.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 95d0e15c-f7c8-41ff-8702-65a61ea6b970

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

…undaries

Snapshot hydration lets everything outside an incomplete streamed
boundary hydrate and move on; only boundaries still streaming hydrate
against the server snapshot. The test pinned the opposite: a resumed
boundary's DOM held the server value until the whole stream closed.

Renamed to "cache writes during the open stream commit immediately
outside pending boundaries": setQueryData and a mid-stream refetch reach
#header at once, the pending feed boundary stays on its fallback and
later hydrates from the server payload without refetching.

Requires the Solid core change that recomputes nodes outside pending
streamed boundaries on client writes.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
ryansolid and others added 2 commits September 29, 2026 22:29
Outside every pending streamed boundary a cache write commits
immediately; under a pending boundary it waits for that boundary to
resume against the server snapshot. Comment only.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
solid-js, @solidjs/web, @solidjs/signals and @solidjs/babel-plugin move
to ^2.0.0-rc.13 across the Solid packages, examples and the vite
integration; the solid-js / @solidjs/web peer floor rises to
>=2.0.0-rc.13, the first release with the public hydration API the
adapter now imports.

@solidjs/vite-plugin moves to ^3.0.0-next.46 so the compiler it loads
is rc.13 as well: next.44 passes a `componentNames` option that
@solidjs/compiler rc.13 rejects, and holding the compiler back at rc.9
would compile against a different runtime than the one installed.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@ryansolid
ryansolid marked this pull request as ready for review September 30, 2026 07:13
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​solidjs/​web@​2.0.0-rc.9 ⏵ 2.0.0-rc.13100 +11008397 +1100
Updated@​solidjs/​babel-plugin@​2.0.0-rc.9 ⏵ 2.0.0-rc.1392 +6100100 +195 +2100
Updatedsolid-js@​2.0.0-rc.9 ⏵ 2.0.0-rc.1310010095 +196100
Updated@​solidjs/​vite-plugin@​3.0.0-next.44 ⏵ 3.0.0-next.4696 -1100100 +196 +1100
Updated@​solidjs/​signals@​2.0.0-rc.9 ⏵ 2.0.0-rc.13100 +1100100 +198 +1100

View full report

@socket-security

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Priority Alert  (click "▶" to expand/collapse) Action
Low priority
Low adoption: npm @solidjs/compiler-darwin-x64

Location: Package overview

From: pnpm-lock.yaml → npm/@solidjs/vite-plugin@3.0.0-next.46 → npm/@solidjs/compiler-darwin-x64@2.0.0-rc.13

ℹ Read more on: This package | This alert | What are unpopular packages?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Unpopular packages may have less maintenance and contain other problems.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@solidjs/compiler-darwin-x64@2.0.0-rc.13. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn

View full report

ryansolid added a commit to nickshiro/solid that referenced this pull request Sep 30, 2026
… onto the live-shell latch until upstream does; fail on install/type-check errors; refetch the fixture

The rc.12 release stopped at the TanStack Solid Query gate: `sharedConfig`
is `@internal` since rc.12, so the adapter's type-check fails with TS2305
(QueryClientProvider.tsx, cacheAggregate.ts, useBaseQuery.ts). The public
hydration API replaces it; until the adapter migrates upstream, the gate
applies that migration (tests/patches/tanstack-solid-query-public-
hydration.diff) to the fetched fixture. Self-removing: the patch applies
only while the fixture still imports `sharedConfig` from solid-js, fails
the gate if it no longer covers every such import, and is skipped once
upstream has none.

The adapter's "cache writes during the open stream commit when hydration
completes" test pins the latch behavior the previous commit fixes (a shell
write waiting for the whole page to hydrate). While the fetched fixture
still carries that test, the gate rewrites it to the new expectation
(tests/patches/tanstack-solid-query-hydration-latch.diff: the write commits
to the shell at once). Self-removing the same way: applied only while the
old title is present, failing the gate if the title survives the patch,
skipped once upstream renames or rewrites it (TanStack/query#11751).
Delete both blocks and patch files after that.

Two gate bugs fixed on the way:
- gitly serves its cached tarball first for any ref but master/main, so
  the gate kept re-testing the first `solid-query-v6-pre` download;
  `download(..., { force: true })` fetches the branch head.
- shelljs's `exec` has no per-call `fatal` (only the global config), so a
  failed `pnpm install` or `pnpm run compile` (the adapter's type-check)
  returned silently. Both now run through a spawn helper that fails the
  gate on a non-zero exit or a signal; `npm pack` checks its exit code.

SKIP_SOLID_QUERY_GATE in scripts/release.mjs is unchanged.

Co-authored-by: Claude via Cursor <noreply@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@nx-cloud

nx-cloud Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit b98c0b8

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

☁️ Nx Cloud last updated this comment at 2026-09-30 19:01:31 UTC

@pkg-pr-new

pkg-pr-new Bot commented Sep 30, 2026

Copy link
Copy Markdown
More templates

@tanstack/angular-query-experimental

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

@tanstack/eslint-plugin-query

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

@tanstack/lit-query

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

@tanstack/preact-query

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

@tanstack/preact-query-devtools

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

@tanstack/preact-query-persist-client

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

@tanstack/query-async-storage-persister

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

@tanstack/query-broadcast-client-experimental

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

@tanstack/query-core

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

@tanstack/query-devtools

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

@tanstack/query-persist-client-core

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

@tanstack/query-sync-storage-persister

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

@tanstack/react-query

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

@tanstack/react-query-devtools

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

@tanstack/react-query-next-experimental

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

@tanstack/react-query-persist-client

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

@tanstack/solid-query

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

@tanstack/solid-query-devtools

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

@tanstack/solid-query-persist-client

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

@tanstack/svelte-query

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

@tanstack/svelte-query-devtools

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

@tanstack/svelte-query-persist-client

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

@tanstack/vue-query

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

@tanstack/vue-query-devtools

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

commit: b98c0b8

@brenelz
brenelz merged commit 8a13b15 into TanStack:solid-query-v6-pre Sep 30, 2026
9 checks passed
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