snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
Some checks failed
autofix.ci / autofix (push) Failing after 4s
Release / Release (push) Has been skipped
GitHub Actions Security Analysis / Run zizmor (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-16 01:13:08 +05:00
commit 3a013ccdfe
3570 changed files with 490194 additions and 0 deletions

9
examples/svelte/playground/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
!lib/

View File

@@ -0,0 +1,8 @@
# Example
This example is a rewrite of the React Query playground example.
To run this example:
- `npm install`
- `npm run dev`

View File

@@ -0,0 +1,23 @@
{
"name": "@tanstack/query-example-svelte-playground",
"private": true,
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@tanstack/svelte-query": "^6.1.48",
"@tanstack/svelte-query-devtools": "^6.1.48"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^6.1.0",
"@sveltejs/kit": "^2.57.1",
"@sveltejs/vite-plugin-svelte": "^5.1.1",
"svelte": "^5.39.3",
"svelte-check": "^4.3.1",
"typescript": "5.8.3",
"vite": "^6.4.1"
}
}

View File

@@ -0,0 +1,11 @@
body {
margin: 0;
padding: 1rem;
font-family:
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: white;
background: #0b1521;
}

12
examples/svelte/playground/src/app.d.ts vendored Normal file
View File

@@ -0,0 +1,12 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}
}
export {}

View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@@ -0,0 +1,37 @@
export function ref<T>(initial: T) {
let value = $state(initial)
return {
get value() {
return value
},
set value(newValue) {
value = newValue
},
}
}
export const staleTime = ref(1000)
export const gcTime = ref(3000)
export const errorRate = ref(0.05)
export const queryTimeMin = ref(1000)
export const queryTimeMax = ref(2000)
export const editingIndex = ref<number | null>(null)
export const views = ref(['', 'fruit', 'grape'])
let initialId = 0
const initialList = [
'apple',
'banana',
'pineapple',
'grapefruit',
'dragonfruit',
'grapes',
].map((d) => ({ id: initialId++, name: d, notes: 'These are some notes' }))
export const list = ref(initialList)
export const id = ref(initialId)
export type Todos = typeof initialList
export type Todo = Todos[0]

View File

@@ -0,0 +1,27 @@
<script lang="ts">
import '../app.css'
import { browser } from '$app/environment'
import { QueryClientProvider, QueryClient } from '@tanstack/svelte-query'
import { SvelteQueryDevtools } from '@tanstack/svelte-query-devtools'
const { children } = $props()
const queryClient = new QueryClient({
defaultOptions: {
queries: {
enabled: browser,
},
},
})
</script>
<svelte:head>
<title>Svelte Query Playground Example</title>
</svelte:head>
<QueryClientProvider client={queryClient}>
<div id="app">
{@render children()}
</div>
<SvelteQueryDevtools />
</QueryClientProvider>

View File

@@ -0,0 +1,81 @@
<script lang="ts">
import { useQueryClient } from '@tanstack/svelte-query'
import {
staleTime,
gcTime,
errorRate,
queryTimeMin,
queryTimeMax,
} from '../lib/stores.svelte'
import App from './App.svelte'
const queryClient = useQueryClient()
queryClient.setDefaultOptions({
queries: {
staleTime: staleTime.value,
gcTime: gcTime.value,
},
})
</script>
<p>
The "staleTime" and "gcTime" durations have been altered in this example to
show how query stale-ness and query caching work on a granular level
</p>
<div>
Stale Time:{' '}
<input
type="number"
min="0"
step="1000"
bind:value={staleTime.value}
style="width: 100px"
/>
</div>
<div>
GcTime:{' '}
<input
type="number"
min="0"
step="1000"
bind:value={gcTime.value}
style="width: 100px"
/>
</div>
<br />
<div>
Error Rate:{' '}
<input
type="number"
min="0"
max="1"
step=".05"
bind:value={errorRate.value}
style="width: 100px"
/>
</div>
<div>
Fetch Time Min:{' '}
<input
type="number"
min="1"
step="500"
bind:value={queryTimeMin.value}
style="width: 100px"
/>{' '}
</div>
<div>
Fetch Time Max:{' '}
<input
type="number"
min="1"
step="500"
bind:value={queryTimeMax.value}
style="width: 100px"
/>
</div>
<br />
<App />
<br />

View File

@@ -0,0 +1,67 @@
<script lang="ts">
import { createMutation, useQueryClient } from '@tanstack/svelte-query'
import {
errorRate,
queryTimeMin,
queryTimeMax,
list,
id,
} from '$lib/stores.svelte'
import type { Todo } from '$lib/stores.svelte'
const queryClient = useQueryClient()
let name = $state('')
const postTodo = async ({ name, notes }: Omit<Todo, 'id'>) => {
return new Promise((resolve, reject) => {
setTimeout(
() => {
if (Math.random() < errorRate.value) {
return reject(
new Error(
JSON.stringify(
{ postTodo: { name: $state.snapshot(name), notes } },
null,
2,
),
),
)
}
const todo = { name, notes, id: id.value }
id.value = id.value + 1
list.value.push(todo)
resolve(todo)
},
queryTimeMin.value +
Math.random() * (queryTimeMax.value - queryTimeMin.value),
)
})
}
const addMutation = createMutation(() => ({
mutationFn: postTodo,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
}))
</script>
<div>
<input bind:value={name} disabled={addMutation.status === 'pending'} />
<button
onclick={() => addMutation.mutate({ name, notes: name })}
disabled={addMutation.status === 'pending' || !name}
>
Add Todo
</button>
<div>
{addMutation.status === 'pending'
? 'Saving...'
: addMutation.status === 'error'
? addMutation.error.message
: 'Saved!'}
</div>
</div>

View File

@@ -0,0 +1,42 @@
<script lang="ts">
import { useQueryClient } from '@tanstack/svelte-query'
import TodosList from './TodosList.svelte'
import EditTodo from './EditTodo.svelte'
import AddTodo from './AddTodo.svelte'
import { views, editingIndex } from '../lib/stores.svelte'
const queryClient = useQueryClient()
</script>
<div>
<div>
<button onclick={() => queryClient.invalidateQueries()}>
Force Refetch All
</button>
</div>
<br />
<hr />
{#each views.value as view}
<div>
<TodosList initialFilter={view} />
<br />
</div>
{/each}
<button
onclick={() => {
views.value.push('')
}}
>
Add Filter List
</button>
<hr />
{#if editingIndex.value !== null}
<EditTodo />
<hr />
{/if}
<AddTodo />
</div>

View File

@@ -0,0 +1,138 @@
<script lang="ts">
import {
useQueryClient,
createQuery,
createMutation,
} from '@tanstack/svelte-query'
import {
errorRate,
queryTimeMin,
queryTimeMax,
list,
editingIndex,
} from '$lib/stores.svelte'
import type { Todo } from '$lib/stores.svelte'
const queryClient = useQueryClient()
const fetchTodoById = async ({ id }: { id: number }): Promise<Todo> => {
return new Promise((resolve, reject) => {
setTimeout(
() => {
if (Math.random() < errorRate.value) {
return reject(
new Error(JSON.stringify({ fetchTodoById: { id } }, null, 2)),
)
}
const todo = $state.snapshot(list.value.find((d) => d.id === id))
if (!todo) {
return reject(
new Error(JSON.stringify({ fetchTodoById: { id } }, null, 2)),
)
}
resolve(todo)
},
queryTimeMin.value +
Math.random() * (queryTimeMax.value - queryTimeMin.value),
)
})
}
function patchTodo(todo?: Todo): Promise<Todo> {
console.info('patchTodo', todo)
return new Promise((resolve, reject) => {
setTimeout(
() => {
if (Math.random() < errorRate.value) {
return reject(
new Error(JSON.stringify({ patchTodo: todo }, null, 2)),
)
}
if (!todo) {
return reject(
new Error(JSON.stringify({ patchTodo: todo }, null, 2)),
)
}
list.value = list.value.map((d) => {
if (d.id === todo.id) {
return $state.snapshot(todo)
}
return d
})
resolve(todo)
},
queryTimeMin.value +
Math.random() * (queryTimeMax.value - queryTimeMin.value),
)
})
}
const query = createQuery(() => ({
queryKey: ['todo', { id: editingIndex.value }],
queryFn: () => fetchTodoById({ id: editingIndex.value || 0 }),
enabled: editingIndex.value !== null,
}))
const saveMutation = createMutation(() => ({
mutationFn: patchTodo,
onSuccess: (data) => {
// Update `todos` and the individual todo queries when this mutation succeeds
queryClient.invalidateQueries({ queryKey: ['todos'] })
queryClient.setQueryData(['todo', { id: editingIndex }], data)
},
}))
const todo = $derived(query.data)
const onSave = () => {
saveMutation.mutate(todo)
}
const disableEditSave = $derived(
query.status === 'pending' || saveMutation.status === 'pending',
)
</script>
<div>
<div>
{#if query.data}
<button onclick={() => (editingIndex.value = null)}>Back</button> Editing
Todo "{query.data.name}" (#{editingIndex.value})
{/if}
</div>
{#if query.status === 'pending'}
<span>Loading... (Attempt: {query.failureCount + 1})</span>
{:else if query.error}
<span>
Error! <button onclick={() => query.refetch()}>Retry</button>
</span>
{:else if todo}
<label>
Name:{' '}
<input bind:value={todo.name} disabled={disableEditSave} />
</label>
<label>
Notes:{' '}
<input bind:value={todo.notes} disabled={disableEditSave} />
</label>
<div>
<button onclick={onSave} disabled={disableEditSave}> Save </button>
</div>
<div>
{saveMutation.status === 'pending'
? 'Saving...'
: saveMutation.status === 'error'
? saveMutation.error.message
: 'Saved!'}
</div>
<div>
{#if query.isFetching}
<span>
Background Refreshing... (Attempt: {query.failureCount + 1})
</span>
{:else}
<span>&nbsp;</span>
{/if}
</div>
{/if}
</div>

View File

@@ -0,0 +1,74 @@
<script lang="ts">
import { createQuery } from '@tanstack/svelte-query'
import {
errorRate,
queryTimeMin,
queryTimeMax,
list,
editingIndex,
} from '$lib/stores.svelte'
import type { Todos } from '$lib/stores.svelte'
let { initialFilter }: { initialFilter: string } = $props()
let filter = $state(initialFilter)
const fetchTodos = async ({ filter }: { filter: string }): Promise<Todos> => {
return new Promise((resolve, reject) => {
setTimeout(
() => {
if (Math.random() < errorRate.value) {
return reject(
new Error(JSON.stringify({ fetchTodos: { filter } }, null, 2)),
)
}
resolve(list.value.filter((d) => d.name.includes(filter)))
},
queryTimeMin.value +
Math.random() * (queryTimeMax.value - queryTimeMin.value),
)
})
}
const query = createQuery(() => ({
queryKey: ['todos', { filter: filter }],
queryFn: () => fetchTodos({ filter: filter }),
}))
</script>
<div>
<label>
Filter:{' '}
<input bind:value={filter} />
</label>
</div>
{#if query.status === 'pending'}
<span>Loading... (Attempt: {query.failureCount + 1})</span>
{:else if query.status === 'error'}
<span>
Error: {query.error.message}
<br />
<button onclick={() => query.refetch()}>Retry</button>
</span>
{:else}
<ul>
{#if query.data}
{#each query.data as todo}
<li>
{todo.name}{' '}
<button onclick={() => (editingIndex.value = todo.id)}> Edit </button>
</li>
{/each}
{/if}
</ul>
<div>
{#if query.isFetching}
<span>
Background Refreshing... (Attempt: {query.failureCount + 1})
</span>
{:else}
<span>&nbsp;</span>
{/if}
</div>
{/if}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,15 @@
import adapter from '@sveltejs/adapter-auto'
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
adapter: adapter(),
},
compilerOptions: {
runes: true,
},
}
export default config

View File

@@ -0,0 +1,13 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
}

View File

@@ -0,0 +1,6 @@
import { sveltekit } from '@sveltejs/kit/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [sveltekit()],
})