Skip to content

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

Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8c9ce99
WIP: Svelte 5 adapter (#6981)
zhihengGet Jul 26, 2024
647cbf9
Merge remote-tracking branch 'origin' into svelte-5-adapter-notes
elliott-with-the-longest-name-on-github Mar 23, 2025
3e60f15
feat: Draft proposal
elliott-with-the-longest-name-on-github Mar 25, 2025
cd2d81f
Merge remote-tracking branch 'origin' into svelte-5-adapter-derived-by
elliott-with-the-longest-name-on-github Mar 25, 2025
fec1a0d
chore: Improve reactive containers
elliott-with-the-longest-name-on-github Mar 25, 2025
5b359ed
ci: apply automated fixes
autofix-ci[bot] Mar 25, 2025
8325a7b
oops
elliott-with-the-longest-name-on-github Mar 25, 2025
a6917da
Merge branch 'svelte-5-adapter-derived-by' of github.com:elliott-with…
elliott-with-the-longest-name-on-github Mar 25, 2025
4c93461
fix: Update API, add a bunch of tests
elliott-with-the-longest-name-on-github Apr 2, 2025
07ab8dd
Merge remote-tracking branch 'origin' into svelte-5-adapter-derived-by
elliott-with-the-longest-name-on-github Apr 2, 2025
c35a54f
merge main
elliott-with-the-longest-name-on-github Apr 2, 2025
cb173e2
fix: use const
elliott-with-the-longest-name-on-github Apr 2, 2025
b7dda3d
more tests
elliott-with-the-longest-name-on-github Apr 2, 2025
cc54952
feat: More tests, back to thunks, fixed svelte-query-persist-client
elliott-with-the-longest-name-on-github Apr 3, 2025
6e73278
feat: More tests and examples!
elliott-with-the-longest-name-on-github Apr 8, 2025
9fdbcad
Merge remote-tracking branch 'upstream/main' into svelte-5-adapter-de…
elliott-with-the-longest-name-on-github Apr 8, 2025
14620d1
lockfile
elliott-with-the-longest-name-on-github Apr 15, 2025
7e542cd
Merge remote-tracking branch 'origin/svelte-5-adapter' into svelte-5-…
elliott-with-the-longest-name-on-github Apr 15, 2025
ba92c7f
fixes
elliott-with-the-longest-name-on-github Apr 15, 2025
dffbdc7
Fix current CI errors
lachlancollins Apr 20, 2025
2452ce9
More small fixes/tweaks
lachlancollins Apr 20, 2025
d0bbe8c
Remove test.only
lachlancollins Apr 20, 2025
fd399fb
ci: apply automated fixes
autofix-ci[bot] Apr 20, 2025
258d992
Fix pnpm-lock, fix import order
lachlancollins Apr 20, 2025
6af7b18
update main docs
elliott-with-the-longest-name-on-github Apr 30, 2025
855fd47
feat: More tests
elliott-with-the-longest-name-on-github May 1, 2025
022cd6b
ci: apply automated fixes
autofix-ci[bot] May 3, 2025
fac45b3
add back old tests
lachlancollins May 12, 2025
5b7ae26
Cleanup
lachlancollins May 12, 2025
a891fd4
Fix persist client
lachlancollins May 12, 2025
ac1ab87
Fix useMutationState
lachlancollins May 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default [
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-unsafe-function-type': 'off',
'no-case-declarations': 'off',
'prefer-const': 'off',
},
},
{
Expand Down
4 changes: 2 additions & 2 deletions examples/svelte/auto-refetching/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"devDependencies": {
"@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/kit": "^2.14.0",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"svelte": "^4.2.18",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"svelte": "^5.20.1",
"svelte-check": "^4.0.0",
"typescript": "5.8.2",
"vite": "^5.3.5"
Expand Down
4 changes: 3 additions & 1 deletion examples/svelte/auto-refetching/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import { QueryClientProvider, QueryClient } from '@tanstack/svelte-query'
import { SvelteQueryDevtools } from '@tanstack/svelte-query-devtools'

const { children } = $props()

const queryClient = new QueryClient({
defaultOptions: {
queries: {
Expand All @@ -15,7 +17,7 @@

<QueryClientProvider client={queryClient}>
<main>
<slot />
{@render children()}
</main>
<SvelteQueryDevtools />
</QueryClientProvider>
40 changes: 19 additions & 21 deletions examples/svelte/auto-refetching/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,30 @@
createMutation,
} from '@tanstack/svelte-query'

let intervalMs = 1000
let value = ''
let intervalMs = $state(1000)
let value = $state<string>('')

const client = useQueryClient()

const endpoint = 'http://localhost:5173/api/data'

$: todos = createQuery<{ items: string[] }>({
const todos = createQuery<{ items: string[] }>(() => ({
queryKey: ['refetch'],
queryFn: async () => await fetch(endpoint).then((r) => r.json()),
// Refetch the data every second
refetchInterval: intervalMs,
})
}))

const addMutation = createMutation({
const addMutation = createMutation(() => ({
mutationFn: (value: string) =>
fetch(`${endpoint}?add=${value}`).then((r) => r.json()),
onSuccess: () => client.invalidateQueries({ queryKey: ['refetch'] }),
})
}))

const clearMutation = createMutation({
const clearMutation = createMutation(() => ({
mutationFn: () => fetch(`${endpoint}?clear=1`).then((r) => r.json()),
onSuccess: () => client.invalidateQueries({ queryKey: ['refetch'] }),
})
}))
</script>

<h1>Auto Refetch with stale-time set to 1s</h1>
Expand All @@ -49,46 +49,44 @@
margin-left:.5rem;
width:.75rem;
height:.75rem;
background: {$todos.isFetching ? 'green' : 'transparent'};
transition: {!$todos.isFetching ? 'all .3s ease' : 'none'};
background: {todos.isFetching ? 'green' : 'transparent'};
transition: {!todos.isFetching ? 'all .3s ease' : 'none'};
border-radius: 100%;
transform: scale(1.5)"
></span>
</div>
</label>
<h2>Todo List</h2>
<form
on:submit={(e) => {
onsubmit={(e) => {
e.preventDefault()
e.stopPropagation()
$addMutation.mutate(value, {
addMutation.mutate(value, {
onSuccess: () => (value = ''),
})
}}
>
<input placeholder="enter something" bind:value />
</form>

{#if $todos.isPending}
{#if todos.isPending}
Loading...
{/if}
{#if $todos.error}
{#if todos.error}
An error has occurred:
{$todos.error.message}
{todos.error.message}
{/if}
{#if $todos.isSuccess}
{#if todos.isSuccess}
<ul>
{#each $todos.data.items as item}
{#each todos.data.items as item}
<li>{item}</li>
{/each}
</ul>
<div>
<button on:click={() => $clearMutation.mutate(undefined)}>
Clear All
</button>
<button onclick={() => clearMutation.mutate(undefined)}> Clear All </button>
</div>
{/if}
{#if $todos.isFetching}
{#if todos.isFetching}
<div style="color:darkgreen; font-weight:700">
'Background Updating...' : ' '
</div>
Expand Down
6 changes: 3 additions & 3 deletions examples/svelte/auto-refetching/svelte.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: vitePreprocess(),

kit: {
adapter: adapter(),
},
compilerOptions: {
runes: true,
},
}

export default config
4 changes: 2 additions & 2 deletions examples/svelte/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
"devDependencies": {
"@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/kit": "^2.14.0",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"svelte": "^4.2.18",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"svelte": "^5.20.1",
"svelte-check": "^4.0.0",
"typescript": "5.8.2",
"vite": "^5.3.5"
Expand Down
20 changes: 10 additions & 10 deletions examples/svelte/basic/src/lib/Post.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@
import { getPostById } from './data'
import type { Post } from './types'

export let postId: number
const { postId }: { postId: number } = $props()

const post = createQuery<Post>({
const post = createQuery<Post>(() => ({
queryKey: ['post', postId],
queryFn: () => getPostById(postId),
})
}))
</script>

<div>
<div>
<a class="button" href="/"> Back </a>
</div>
{#if !postId || $post.isPending}
{#if !postId || post.isPending}
<span>Loading...</span>
{/if}
{#if $post.error}
<span>Error: {$post.error.message}</span>
{#if post.error}
<span>Error: {post.error.message}</span>
{/if}
{#if $post.isSuccess}
<h1>{$post.data.title}</h1>
{#if post.isSuccess}
<h1>{post.data.title}</h1>
<div>
<p>{$post.data.body}</p>
<p>{post.data.body}</p>
</div>
<div>{$post.isFetching ? 'Background Updating...' : ' '}</div>
<div>{post.isFetching ? 'Background Updating...' : ' '}</div>
{/if}
</div>
14 changes: 7 additions & 7 deletions examples/svelte/basic/src/lib/Posts.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@
const posts = createQuery<
{ id: number; title: string; body: string }[],
Error
>({
>(() => ({
queryKey: ['posts', limit],
queryFn: () => getPosts(limit),
})
}))
</script>

<div>
<div>
{#if $posts.status === 'pending'}
{#if posts.status === 'pending'}
<span>Loading...</span>
{:else if $posts.status === 'error'}
<span>Error: {$posts.error.message}</span>
{:else if posts.status === 'error'}
<span>Error: {posts.error.message}</span>
{:else}
<ul>
{#each $posts.data as post}
{#each posts.data as post}
<article>
<a
href={`/${post.id}`}
Expand All @@ -38,7 +38,7 @@
</article>
{/each}
</ul>
{#if $posts.isFetching}
{#if posts.isFetching}
<div style="color:darkgreen; font-weight:700">
Background Updating...
</div>
Expand Down
4 changes: 3 additions & 1 deletion examples/svelte/basic/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import { PersistQueryClientProvider } from '@tanstack/svelte-query-persist-client'
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'

const { children } = $props()

const queryClient = new QueryClient({
defaultOptions: {
queries: {
Expand All @@ -21,7 +23,7 @@

<PersistQueryClientProvider client={queryClient} persistOptions={{ persister }}>
<main>
<slot />
{@render children()}
</main>
<SvelteQueryDevtools />
</PersistQueryClientProvider>
3 changes: 1 addition & 2 deletions examples/svelte/basic/src/routes/[postId]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<script lang="ts">
import Post from '$lib/Post.svelte'
import type { PageData } from './$types'

export let data: PageData
const { data } = $props()
</script>

<Post postId={data.postId} />
6 changes: 3 additions & 3 deletions examples/svelte/basic/svelte.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: vitePreprocess(),

kit: {
adapter: adapter(),
},
compilerOptions: {
runes: true,
},
}

export default config
4 changes: 2 additions & 2 deletions examples/svelte/load-more-infinite-scroll/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"devDependencies": {
"@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/kit": "^2.14.0",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"svelte": "^4.2.18",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"svelte": "^5.20.1",
"svelte-check": "^4.0.0",
"typescript": "5.8.2",
"vite": "^5.3.5"
Expand Down
10 changes: 5 additions & 5 deletions examples/svelte/load-more-infinite-scroll/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ main {
text-align: center;
}

button {
.button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
Expand All @@ -59,11 +59,11 @@ button {
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
.button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
.button:focus,
.button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}

Expand All @@ -75,7 +75,7 @@ button:focus-visible {
a:hover {
color: #747bff;
}
button {
.button {
background-color: #f9f9f9;
}
}
22 changes: 11 additions & 11 deletions examples/svelte/load-more-infinite-scroll/src/lib/LoadMore.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
const fetchPlanets = async ({ pageParam = 1 }) =>
await fetch(`${endPoint}/planets/?page=${pageParam}`).then((r) => r.json())

const query = createInfiniteQuery({
const query = createInfiniteQuery(() => ({
queryKey: ['planets'],
queryFn: ({ pageParam }) => fetchPlanets({ pageParam }),
initialPageParam: 1,
Expand All @@ -20,18 +20,18 @@
}
return undefined
},
})
}))
</script>

{#if $query.isPending}
{#if query.isPending}
Loading...
{/if}
{#if $query.error}
<span>Error: {$query.error.message}</span>
{#if query.error}
<span>Error: {query.error.message}</span>
{/if}
{#if $query.isSuccess}
{#if query.isSuccess}
<div>
{#each $query.data.pages as { results }}
{#each query.data.pages as { results }}
{#each results as planet}
<div class="card">
<div class="card-body">
Expand All @@ -44,12 +44,12 @@
</div>
<div>
<button
on:click={() => $query.fetchNextPage()}
disabled={!$query.hasNextPage || $query.isFetchingNextPage}
onclick={() => query.fetchNextPage()}
disabled={!query.hasNextPage || query.isFetchingNextPage}
>
{#if $query.isFetching}
{#if query.isFetching}
Loading more...
{:else if $query.hasNextPage}
{:else if query.hasNextPage}
Load More
{:else}Nothing more to load{/if}
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import { QueryClientProvider, QueryClient } from '@tanstack/svelte-query'
import { SvelteQueryDevtools } from '@tanstack/svelte-query-devtools'

const { children } = $props()

const queryClient = new QueryClient({
defaultOptions: {
queries: {
Expand All @@ -15,7 +17,7 @@

<QueryClientProvider client={queryClient}>
<main>
<slot />
{@render children()}
</main>
<SvelteQueryDevtools />
</QueryClientProvider>
Loading
Loading