feat(solid): named single-flight source + loadFlightTarget, the cache-agnostic trigger - #8192
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
…els carry the Router + Query pairing solid-query v6's QueryClientProvider serializes the request's cache into Solid's hydration registry during SSR and primes the client cache from it, so running the ssr-query transport alongside it ships every query payload twice. The package's two runtime conveniences are each a few lines of userland composition on public APIs: the provider wrap via the router's Wrap option, and cache-driven redirect() errors handed to router.navigate from the caches' config.onError. Converts the three Solid Start e2e apps to the composition (all suites green, including the redirect-from-query tests) and marks the package deprecated for the v2 line. Co-authored-by: Cursor <cursoragent@cursor.com>
|
View your CI Pipeline Execution ↗ for commit 6c51a06
☁️ Nx Cloud last updated this comment at |
Hooray! CodSpeed harness just leveled up!The base and head of this comparison were measured with different runner settings, so their benchmark values are not directly comparable. What changed between base and head:
Re-run the base with the same settings to get a valid performance comparison. Comparing Footnotes |
|
Pushed two additions: |
356e016 to
6b5dea0
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Co-authored-by: Cursor <cursoragent@cursor.com>
Solid's single-flight channel is becoming multi-source (solidjs/solid 653dd41e): mutation responses carry a keyed envelope of per-cache slices, each routed to the consumer subscribed under its source id. Today Start claims the single unnamed slot on both halves, which means any other cache wanting mutation-response data (e.g. solid-query, whose provider subscribes under "sq" in TanStack/query#11326) displaces the router's — whichever registers last wins, silently. The router's flight data now rides its own source id ("tsr"): the server collector registers additively with registerFlightDataSource and the client subscribes its consumer under the same id, so router loader/match state and other caches' slices coexist on one round trip. A user-supplied collectFlightData hook keeps the unnamed slot to itself, adding data alongside the router's instead of displacing it. Both halves feature-detect the protocol on the installed @solidjs/web (it ships in the release after 2.0.0-rc.4) and fall back to the exact previous unnamed-slot behavior on older versions; since client and server resolve the same install, the halves cannot disagree. Co-authored-by: Cursor <cursoragent@cursor.com>
…t trigger The router's half of flight collection as a public primitive: derive the flight request for the mutation's target, run the matched routes' data functions, hand the loaded router to the caller's collect() — any cache (the router's own state, a query client) composes its extraction on top. Start's collector now consumes it; errors are contained per Solid Router's collector convention (flight data is an optimization, never a mutation error). Co-authored-by: Cursor <cursoragent@cursor.com>
…5 fallback @solidjs/web 2.0.0-rc.5 ships the multi-source single-flight protocol, so the feature detection and cast shims bridging unreleased types come out: the client subscribes directly under SOLID_START_FLIGHT_SOURCE, the server registers its collector via registerFlightDataSource unconditionally (the unnamed collectFlightData slot now always belongs to the user), and the @solidjs/web peer floor moves to rc.5. Co-authored-by: Cursor <cursoragent@cursor.com>
With the pre-rc.5 fallback stripped, the client advertises its named source and the server echoes what it folded: X-Single-Flight is "tsr" on both sides, not the legacy "true". Co-authored-by: Cursor <cursoragent@cursor.com>
62c7702 to
1f6e3d9
Compare
|
Benchmarks are failing with |
|
And some e2e with
|
…rc.6 Repo-wide (packages, examples, e2e apps, benchmarks) — a scoped bump leaves the workspace mixed, and examples/benchmarks then build workspace solid-start dists (which import registerFlightDataSource, rc.5+) against their own @solidjs/web rc.4 resolution. rc.6 ships the named flight-data source API this branch requires plus the settle-walk fix that unblocks the Solid Query pairing. @tanstack/solid-start's peer floor moves to rc.6. The SSR bench helpers move onto rc.6's wire shape: scripted callers use the data address (`<endpoint>/data/<id>`) — the bare address now answers document traffic with the no-JS convention. Co-authored-by: Cursor <cursoragent@cursor.com>
1f6e3d9 to
21b2fc6
Compare
There was a problem hiding this comment.
Nx Cloud is proposing a fix for your failed CI:
We updated all createEffect usages in the solid example apps to match the breaking API change introduced in solid-js rc.6, where the function now requires two mandatory arguments (a reactive compute phase and a separate effectFn phase) instead of the previous single-callback form. These changes fix the TS2554: Expected 2-3 arguments, but got 1 TypeScript errors that caused four example build tasks to fail after the PR bumped solid-js from rc.4 to rc.6 without updating the call sites.
Tip
✅ We verified this fix by re-running tanstack-router-solid-example-kitchen-sink-solid-query:build, tanstack-router-solid-example-basic-solid-query:build, tanstack-router-solid-example-basic-solid-query-file-based:build and 2 more.
Warning
The suggested diff is too large to display here, but you can view it on Nx Cloud ↗
Because this branch comes from a fork, it is not possible for us to apply fixes directly, but you can apply the changes locally using the available options below.
Apply changes locally with:
npx nx-cloud apply-locally 4KrC-XYcS
Apply fix locally with your editor ↗ View interactive diff ↗
🎓 Learn more about Self-Healing CI on nx.dev
Requires solid-js /
@solidjs/web2.0.0-rc.6 (released) — the branch bumps the Start packages and e2e apps to rc.6 and floors the peer range there. Stacked on #8193 (merge that first): the retiredsetupRouterSsrQueryIntegrationbreaks on rc.6, so the e2e apps must be on the userland glue before this lands.Summary
Solid's single-flight channel is multi-source: a mutation response carries a keyed envelope of per-cache slices, each routed to the consumer subscribed under its source id. Previously Start claimed the single unnamed slot on both halves — so any other cache wanting mutation-response data (e.g. solid-query, whose provider subscribes under
"sq"in TanStack/query#11326) displaced the router's flight data: whichever library registered last silently won.This PR moves the router's flight data onto its own source id (
"tsr"):collectSolidStartFlightDataregisters additively viaregisterFlightDataSource(SOLID_START_FLIGHT_SOURCE, ...)instead of claiming the per-handler unnamed slot. A user-suppliedcollectFlightDataoption now keeps the unnamed slot to itself — its data folds alongside the router's rather than replacing it.Net effect: a Start app using solid-query gets router loader/match refresh and query-cache hydration from one mutation round trip, with no coordination between the libraries.
loadFlightTarget: the trigger as a public primitiveThe factoring behind multi-source flight is: the router owns the trigger (running the matched routes' data functions for the URL the client will show after the mutation), each cache owns its slice (what to extract from the loaded state). This PR makes the trigger public —
loadFlightTargetin@tanstack/solid-router/ssr/server:It derives the flight request (the outcome's pre-digested
targetUrl, the mutation's cookie effects already folded in), points the router at the target through a fresh memory history, runsrouter.load()inside the flight request-event scope, and hands the loaded router tocollect. Errors are contained per Solid Router's own collector convention — flight data is an optimization, so a failure omits the slice rather than surfacing as a mutation error (core also contains per-source: solidjs/solid@ec523607).Start's
tsrcollector consumes the same primitive, keeping only its bespoke halves: start-context acquisition, its serialized-redirect target resolution, and match-state extraction.Known divergence from Solid Router's collector, deliberate for now:
outcome.revalidateKeysscoping isn't honored — it comes from Solid'sX-Revalidateconvention, which TanStack mutations don't produce.Pre-landing checklist (rc.6 shipped — all done)
solid-rpc-flight-client.ts(getFlightDataSourceIdsprobe) — subscribes directly underSOLID_START_FLIGHT_SOURCE.server-functions-handler.ts(the unnamedcollectFlightData-slot assignment) — registers viaregisterFlightDataSourceunconditionally.@solidjs/webpeer floor — floored at rc.6 rather than rc.5, since rc.5's settle-walk regression breaks the solid-query pairing this protocol exists for.Compatibility
@solidjs/web2.0.0-rc.6+ on both halves; client and server resolve the same install, so the halves cannot disagree.isSolidStartFlightDatashape guard stays — redundant-but-harmless under named sources.Verification
nx build @tanstack/solid-routerandnx build @tanstack/solid-startgreen,publint --strict+attwpass.fullstack-tanstack(solid-v2/fullstack-tanstack: multi-source single-flight solidjs/templates#287), which uses exactly theloadFlightTarget+dehydrateSettledcomposition above.e2e/solid-start/server-functions) runs on rc.6 with the named path active (X-Single-Flight: tsr): 29 passed, 1 skipped, locally — on top of refactor(solid): retire solid-router-ssr-query — native channels carry the Router + Query pairing #8193's userland query glue.Made with Cursor