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,41 @@
<script lang="ts">
import type { QueryClient } from '@tanstack/query-core'
import {
createMutation,
setQueryClientContext,
useMutationState,
} from '../../src/index.js'
import type {
Accessor,
CreateMutationOptions,
MutationStateOptions,
} from '../../src/index.js'
type Props = {
queryClient: QueryClient
successMutationOpts: Accessor<CreateMutationOptions<string>>
errorMutationOpts: Accessor<CreateMutationOptions<string>>
mutationStateOpts?: MutationStateOptions
}
let {
queryClient,
successMutationOpts,
errorMutationOpts,
mutationStateOpts,
}: Props = $props()
setQueryClientContext(queryClient)
const successMutation = createMutation(successMutationOpts)
const errorMutation = createMutation(errorMutationOpts)
const mutationState = useMutationState(mutationStateOpts)
</script>
<button onclick={() => successMutation.mutate()}>Success</button>
<button onclick={() => errorMutation.mutate()}>Error</button>
<div>
Data: {JSON.stringify(mutationState.map((state) => state.status))}
</div>

View File

@@ -0,0 +1,33 @@
<script lang="ts">
import type { QueryClient } from '@tanstack/query-core'
import {
createMutation,
setQueryClientContext,
useMutationState,
} from '../../src/index.js'
import type {
Accessor,
CreateMutationOptions,
MutationStateOptions,
} from '../../src/index.js'
type Props = {
queryClient: QueryClient
mutationOpts: Accessor<CreateMutationOptions<string>>
mutationStateOpts: MutationStateOptions<string>
}
let { queryClient, mutationOpts, mutationStateOpts }: Props = $props()
setQueryClientContext(queryClient)
const mutation = createMutation(mutationOpts)
const variables = useMutationState(mutationStateOpts)
</script>
<button onclick={() => mutation.mutate()}>mutate</button>
<div>
Variables: {JSON.stringify(variables)}
</div>

View File

@@ -0,0 +1,195 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { fireEvent, render } from '@testing-library/svelte'
import { QueryClient } from '@tanstack/query-core'
import { queryKey, sleep } from '@tanstack/query-test-utils'
import Base from './Base.svelte'
import Select from './Select.svelte'
import type { Mutation } from '@tanstack/query-core'
describe('useMutationState', () => {
let queryClient: QueryClient
beforeEach(() => {
vi.useFakeTimers()
queryClient = new QueryClient()
})
afterEach(() => {
queryClient.clear()
vi.useRealTimers()
})
it('should run few mutation functions and check from useMutationState', async () => {
const successKey = queryKey()
const errorKey = queryKey()
const successMutationFn = vi.fn(() => sleep(10).then(() => 'data'))
const errorMutationFn = vi
.fn()
.mockImplementation(() =>
sleep(20).then(() => Promise.reject(new Error('error'))),
)
const rendered = render(Base, {
props: {
queryClient,
successMutationOpts: () => ({
mutationKey: successKey,
mutationFn: successMutationFn,
}),
errorMutationOpts: () => ({
mutationKey: errorKey,
mutationFn: errorMutationFn,
}),
},
})
fireEvent.click(rendered.getByRole('button', { name: /Success/i }))
await vi.advanceTimersByTimeAsync(10)
expect(successMutationFn).toHaveBeenCalledTimes(1)
expect(rendered.getByText('Data: ["success"]')).toBeInTheDocument()
fireEvent.click(rendered.getByRole('button', { name: /Error/i }))
await vi.advanceTimersByTimeAsync(20)
expect(errorMutationFn).toHaveBeenCalledTimes(1)
expect(rendered.getByText('Data: ["success","error"]')).toBeInTheDocument()
})
it('should select specific type of mutation ( i.e: error only )', async () => {
const successKey = queryKey()
const errorKey = queryKey()
const successMutationFn = vi.fn(() => sleep(10).then(() => 'data'))
const errorMutationFn = vi
.fn()
.mockImplementation(() =>
sleep(20).then(() => Promise.reject(new Error('error'))),
)
const rendered = render(Base, {
props: {
queryClient,
successMutationOpts: () => ({
mutationKey: successKey,
mutationFn: successMutationFn,
}),
errorMutationOpts: () => ({
mutationKey: errorKey,
mutationFn: errorMutationFn,
}),
mutationStateOpts: {
filters: { status: 'error' },
},
},
})
fireEvent.click(rendered.getByRole('button', { name: /Success/i }))
await vi.advanceTimersByTimeAsync(10)
expect(successMutationFn).toHaveBeenCalledTimes(1)
expect(rendered.getByText('Data: []')).toBeInTheDocument()
fireEvent.click(rendered.getByRole('button', { name: /Error/i }))
await vi.advanceTimersByTimeAsync(20)
expect(errorMutationFn).toHaveBeenCalledTimes(1)
expect(rendered.getByText('Data: ["error"]')).toBeInTheDocument()
})
it('should return selected value when using select option', async () => {
const mutationKey = queryKey()
const rendered = render(Select, {
props: {
queryClient,
mutationOpts: () => ({
mutationKey,
mutationFn: () => sleep(10).then(() => 'data'),
}),
mutationStateOpts: {
filters: { mutationKey },
select: (mutation: Mutation) => mutation.state.status,
},
},
})
expect(rendered.getByText('Variables: []')).toBeInTheDocument()
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
await vi.advanceTimersByTimeAsync(0)
expect(rendered.getByText('Variables: ["pending"]')).toBeInTheDocument()
await vi.advanceTimersByTimeAsync(10)
expect(rendered.getByText('Variables: ["success"]')).toBeInTheDocument()
})
it('should select specific mutation using mutation key', async () => {
const successKey = queryKey()
const errorKey = queryKey()
const successMutationFn = vi.fn(() => sleep(10).then(() => 'data'))
const errorMutationFn = vi
.fn()
.mockImplementation(() =>
sleep(20).then(() => Promise.reject(new Error('error'))),
)
const rendered = render(Base, {
props: {
queryClient,
successMutationOpts: () => ({
mutationKey: successKey,
mutationFn: successMutationFn,
}),
errorMutationOpts: () => ({
mutationKey: errorKey,
mutationFn: errorMutationFn,
}),
mutationStateOpts: {
filters: { mutationKey: successKey },
},
},
})
fireEvent.click(rendered.getByRole('button', { name: /Success/i }))
await vi.advanceTimersByTimeAsync(10)
expect(successMutationFn).toHaveBeenCalledTimes(1)
expect(rendered.getByText('Data: ["success"]')).toBeInTheDocument()
fireEvent.click(rendered.getByRole('button', { name: /Error/i }))
await vi.advanceTimersByTimeAsync(20)
expect(errorMutationFn).toHaveBeenCalledTimes(1)
expect(rendered.getByText('Data: ["success"]')).toBeInTheDocument()
})
it('should remove mutations that no longer match the filter', async () => {
const firstKey = queryKey()
const secondKey = queryKey()
const mutationFn = vi.fn(() => sleep(10).then(() => 'data'))
const rendered = render(Base, {
props: {
queryClient,
successMutationOpts: () => ({
mutationKey: firstKey,
mutationFn,
}),
errorMutationOpts: () => ({
mutationKey: secondKey,
mutationFn,
}),
mutationStateOpts: {
filters: { status: 'pending' },
},
},
})
fireEvent.click(rendered.getByRole('button', { name: /Success/i }))
fireEvent.click(rendered.getByRole('button', { name: /Error/i }))
await vi.advanceTimersByTimeAsync(0)
expect(
rendered.getByText('Data: ["pending","pending"]'),
).toBeInTheDocument()
await vi.advanceTimersByTimeAsync(10)
expect(rendered.getByText('Data: []')).toBeInTheDocument()
})
})

View File

@@ -0,0 +1,24 @@
import { describe, expectTypeOf, it } from 'vitest'
import { useMutationState } from '../../src/index.js'
import type { MutationState, MutationStatus } from '@tanstack/query-core'
describe('useMutationState', () => {
it('should default to MutationState', () => {
const result = useMutationState({
filters: { status: 'pending' },
})
expectTypeOf(result).toEqualTypeOf<
Array<MutationState<unknown, Error, unknown, unknown>>
>()
})
it('should infer with select', () => {
const result = useMutationState({
filters: { status: 'pending' },
select: (mutation) => mutation.state.status,
})
expectTypeOf(result).toEqualTypeOf<Array<MutationStatus>>()
})
})