-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
feat: Svelte 5 API proposal #8852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Svelte 5 API proposal #8852
Conversation
docs(svelte-5-adapter): force runes mode for all examples (TanStack#7800) * docs(examples): force runes mode for all examples * Fix simple example mounting * Fix type feat(svelte-5-adapter): require options to be passed as function (TanStack#7804) * fix(svelte-5-adapter): Require options to be passed as function * More fixes * More fixes * Update examples fix(svelte-5-adapter): function for `createMutation` options (TanStack#7805) * fix(svelte-5-adapter): require function for createMutation options * Fix type errors refactor(svelte-5-adapter): simplify createBaseQuery (TanStack#7808) * refactor: simplify createBaseQuery * Don't take snapshot of queryKey chore(svelte-5-adapter): tidy-up functions (TanStack#7809) * chore(svelte-5-adapter): tidy-up functions * Fix types * Update svelte Fix import extensions chore: ignore state_snapshot_uncloneable in tests Fix merge
View your CI Pipeline Execution ↗ for commit ac1ab87.
☁️ Nx Cloud last updated this comment at |
…-the-longest-name-on-github/tanstack-query into svelte-5-adapter-derived-by
Isn't it a bad thing to have so many $effects? Also how does this work for export scenarios like this where all of my queries are exported https://github.com/exceptionless/Exceptionless/blob/main/src/Exceptionless.Web/ClientApp/src/lib/features/projects/api.svelte.ts currently feels weird and I've been trying to rework params... |
Can you expand upon what you mean? There aren't many effects here, right? Effects in and of themselves aren't bad things, they just become bad things if misused. In this case, there's really no way to synchronize state with an external system (
Basically, you'd just wrap those query exports in const { data, isLoading } = $derived.by(getOrganizationProjectsQuery(...)); |
const data = createQuery(()=>{ ... }) //passing function and directly mutate data for optimistic updates, not sure if it is the best practice tho
const { data, isLoading, ...etc } = $derived.by( // if u want to spread it... then you need $derived.by, but i prefer not doing it
data
); const { data, isLoading, ...etc } = $derived.by( // you can't directly mutate data I believe ? in recent version, we can assign stuff to $derived for optimistic updates but mutate $state feels better? subjective
createQuery({ queryKey, queryFn })
); |
As far as optimistic updates go:
|
Doesn't really matter to me but feels like it's way less idiomatic and I don't like seeing framework code. |
I'm curious -- what idioms are you referring to? The alternative API is basically what we had before: const query = createQuery(() => ({ queryKey, queryFn })) Downsides being:
As far as idioms go, you basically need a thunk on the way in (to preserve argument reactivity) or on the way out (to preserve return value reactivity) -- but not both. Svelte is designed to handle thunk returns gracefully with Either way, the optimistic updates thing above applies -- this shouldn't be implemented with |
I find the example from proposal very elegant 👍 Avoiding the need to use functions for the arguments is amazing, and since queries do depend on outside variables (like the query key) it does make perfect sense that you'd need to wrap it in a |
Having $derived.by at every callsite doesn't feel like just writing javascript (idomatic). And I agree I don't like passing functions either (which seems worse) and not intuitive on what should be a function or not. I have not been destructuring at all here because I haven't seen anyone else do it for tanstack nor the docs (unless they've been updated). I'm always concerned about broken references e.g., isSuccess (computed) being updated properly when destructured? I agree with this as well:
On final note, I'm fine with what ever design but for the sake of porting docs / and samples would be great to have the least amount of changes as possible as svelte doesn't get much love from tanstack docs/community updating those (And I get I could contribute there as well, time is very very limited). Thanks again! |
I just want to point out that "every callsite" is not technically correct, though I expect what you mean is probably true. This would absolutely work: const query = createQuery({ queryKey, queryFn }) ...you just can't destructure it, and More practically, though, you definitely don't need it when creating your own queries: function createUserQuery({ id }) {
return createQuery({
queryKey: ['user', id],
queryFn: ({ queryKey }) => fetch(`/api/users/${queryKey[1]}`).then(r => r.json)
})
} ...you would just need it where you actually use the query: const { data, isLoading } = $derived.by(
createUserQuery({ id })
)
To answer the surface-level question, so long as you're using
This has been the beast I've had to struggle with, especially the intuitiveness part. Maybe for some insanely-bleeding-edge, maximum-possible-performance-needed scenarios it makes sense to fully take advantage of fine-grained reactivity by passing individual getters or functions across the hook boundary, but Tanstack Query is not that use case, especially since all of its state is already externally hosted in
Yeah definitely, this won't go live without updated docs and examples. I'm actually working on porting all of the React tests as well, as the current coverage is pretty abysmal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for your work @elliott-with-the-longest-name-on-github ! After a fair bit of thinking, I agree this syntax is the more svelte v5-appropriate choice. @arnolicious 's comment sums it up well:
Avoiding the need to use functions for the arguments is amazing, and since queries do depend on outside variables (like the query key) it does make perfect sense that you'd need to wrap it in a
derived
(derived.by
), like any other derived value.
Giving a big 👍 to keep working on this!
Also I think it would be more appropriate for the PR to target the TanStack:svelte-5-adapter
branch, so we're comparing the two runes implementations.
I'll re-target the branch -- I had it pointing at |
How will using variables in queryKey work without createQuery accepting a callback? let search = $state('')
const query = createQuery(() => ({
queryKey: ['products', search],
queryFn: async () => {
const data = await fetch(`https://dummyjson.com/products/search?q=${search}`).then((r) => r.json())
return data.products
}) But in this version I couldn't make it work |
Since createQuery now returns a thunk ( const query = $derived.by(createQuery({
queryKey: ['products', search],
queryFn: async () => {
const data = await fetch(`https://dummyjson.com/products/search?q=${search}`).then((r) => r.json())
return data.products
})); |
@Thiagolino8 oh I see... Yeah, that's a problem. You can get around it by passing your own thunk to |
This would recreate the query on every state change |
In this case, I feel like the original solution of passing the query options as a thunk might be more ideal. Another alternative I can think of would be to support passing a thunk to Given that the solid adapter already sets a precedent for passing a thunk to |
I agree. The original solution is a much better DX than the derived one. It
also wouldn’t be an unprecedented API from a Tanstack Query perspective as
the Angular variant also requires a thunk.
…On Mon, Mar 31, 2025 at 7:28 PM David ***@***.***> wrote:
In this case, I feel like the original solution of passing the query
options as a thunk might be more ideal.
Another alternative I can think of would be to support passing a thunk to
queryKey and/or values as thunks within the queryKey array. But then
using the values in queryFn feels sort of disjointed.
Given that the solid adapter already sets a precedent for passing a thunk
to createQuery, I feel that might be the superior solution after all.
There is also precedent among Svelte maintainers
<sveltejs/svelte#12800 (comment)>
that this is the way to go for maintaining reactivity.
—
Reply to this email directly, view it on GitHub
<#8852 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AY6KRUCZRJ7FNNC62PQ44S32XHFRFAVCNFSM6AAAAABZWVCG4SVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDONRXGY2DEOBWGQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
[image: hmnd]*hmnd* left a comment (TanStack/query#8852)
<#8852 (comment)>
In this case, I feel like the original solution of passing the query
options as a thunk might be more ideal.
Another alternative I can think of would be to support passing a thunk to
queryKey and/or values as thunks within the queryKey array. But then
using the values in queryFn feels sort of disjointed.
Given that the solid adapter already sets a precedent for passing a thunk
to createQuery, I feel that might be the superior solution after all.
There is also precedent among Svelte maintainers
<sveltejs/svelte#12800 (comment)>
that this is the way to go for maintaining reactivity.
—
Reply to this email directly, view it on GitHub
<#8852 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AY6KRUCZRJ7FNNC62PQ44S32XHFRFAVCNFSM6AAAAABZWVCG4SVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDONRXGY2DEOBWGQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
FYI to anyone watching, if you end up with a couple of spare hours and want to help out, you can port some tests! I'm using the Solid ones because they're very similar to Svelte, and you can follow along with the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@elliott-with-the-longest-name-on-github when you get a chance, can you target the PR against TanStack:svelte-5-adapter
? I've just rebased that branch onto TanStack:main
(it was a few months behind), so there should hopefully be fewer conflicts.
@lachlancollins apologies for the delay -- I'm actually prepping for my wedding so it's a hectic time 😆 I got it rebased and un-conflicted with your branch -- I think it's pretty well ready to go save for the tests -- there are still a bunch to port over from the Solid library. I'm hoping to be able to bash those out tomorrow and the day after. |
Hi all, I have been following along your amazing work here and thank you for all your hard work! I just saw that the docs were updated to have correct examples of the new API proposal. Would it be possible to also add an example about how a reactive variable with |
@firatciftci passing in the thunk ( |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## svelte-5-adapter #8852 +/- ##
====================================================
- Coverage 44.15% 43.56% -0.59%
====================================================
Files 171 184 +13
Lines 6994 7894 +900
Branches 1574 1749 +175
====================================================
+ Hits 3088 3439 +351
- Misses 3546 4032 +486
- Partials 360 423 +63 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@elliott-with-the-longest-name-on-github I've made a few changes here, with the goal to merge this current work into svelte-5-adapter
, and keep working on that branch rather than this PR.
I've added back the old tests which haven't yet been migrated. This identified issues with createMutation
and useMutationState
, so I've reverted these changes for now.
I also noticed that test-d
files weren't being run by the split client/server tests, and this was also generating a bunch of document
missing errors once these files were re-tested, so I've reverted this split testing for now.
Thanks heaps for all the work you've put in so far, it's certainly getting close to release now!
See the upstream PR that this is based against. This adds more efficiency and a ton of tests!