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

View File

@@ -0,0 +1,28 @@
export interface Todo {
id: string
text: string
createdAt: number
}
export const todos: Array<Todo> = [
{
id: crypto.randomUUID(),
text: 'Buy groceries',
createdAt: Date.now() - 3000,
},
{
id: crypto.randomUUID(),
text: 'Walk the dog',
createdAt: Date.now() - 2000,
},
{
id: crypto.randomUUID(),
text: 'Read a book',
createdAt: Date.now() - 1000,
},
]
export async function getTodos(): Promise<Array<Todo>> {
await new Promise((resolve) => setTimeout(resolve, 200))
return todos
}

View File

@@ -0,0 +1,46 @@
import { NextResponse } from 'next/server'
import { todos, getTodos, type Todo } from './data'
export async function GET() {
return NextResponse.json(await getTodos())
}
export async function POST(request: Request) {
let body: unknown
try {
body = await request.json()
} catch {
return NextResponse.json({ error: 'text is required' }, { status: 400 })
}
const text =
body !== null &&
typeof body === 'object' &&
'text' in body &&
typeof (body as { text: unknown }).text === 'string'
? (body as { text: string }).text.trim()
: ''
if (!text) {
return NextResponse.json({ error: 'text is required' }, { status: 400 })
}
await new Promise((resolve) => setTimeout(resolve, 500))
if (Math.random() < 0.3) {
return NextResponse.json(
{ error: 'Server error — please try again' },
{ status: 500 },
)
}
const newTodo: Todo = {
id: crypto.randomUUID(),
text,
createdAt: Date.now(),
}
todos.push(newTodo)
return NextResponse.json(newTodo, { status: 201 })
}

View File

@@ -0,0 +1,31 @@
import {
QueryClient,
defaultShouldDehydrateQuery,
environmentManager,
} from '@tanstack/react-query'
function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000,
},
dehydrate: {
shouldDehydrateQuery: (query) =>
defaultShouldDehydrateQuery(query) ||
query.state.status === 'pending',
},
},
})
}
let browserQueryClient: QueryClient | undefined = undefined
export function getQueryClient() {
if (environmentManager.isServer()) {
return makeQueryClient()
} else {
if (!browserQueryClient) browserQueryClient = makeQueryClient()
return browserQueryClient
}
}

View File

@@ -0,0 +1,22 @@
import Providers from './providers'
import type React from 'react'
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'TanStack Query — Optimistic Updates',
description: 'Next.js App Router example with optimistic updates',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
)
}

View File

@@ -0,0 +1,29 @@
import React from 'react'
import { HydrationBoundary, dehydrate, noop } from '@tanstack/react-query'
import { getQueryClient } from '@/app/get-query-client'
import { getTodos } from '@/app/api/todos/data'
import ApproachTabs from '@/components/ApproachTabs'
export default function Home() {
const queryClient = getQueryClient()
void queryClient
.query({
queryKey: ['todos'],
queryFn: getTodos,
})
.catch(noop)
return (
<main style={{ maxWidth: 600, margin: '0 auto', padding: '2rem 1rem' }}>
<h1>Optimistic Updates with TanStack Query</h1>
<p style={{ color: '#666', marginBottom: '1.5rem' }}>
Add todos to see optimistic updates in action. The server randomly fails
~30% of the time so you can observe automatic rollback.
</p>
<HydrationBoundary state={dehydrate(queryClient)}>
<ApproachTabs />
</HydrationBoundary>
</main>
)
}

View File

@@ -0,0 +1,16 @@
'use client'
import { QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { getQueryClient } from '@/app/get-query-client'
import type * as React from 'react'
export default function Providers({ children }: { children: React.ReactNode }) {
const queryClient = getQueryClient()
return (
<QueryClientProvider client={queryClient}>
{children}
<ReactQueryDevtools />
</QueryClientProvider>
)
}