Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/fix-svelte-use-mutation-state-shrink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack/svelte-query": patch
---

fix(svelte-query): use splice in useMutationState so the result array shrinks when mutations no longer match the filter
2 changes: 1 addition & 1 deletion packages/svelte-query/src/useMutationState.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function useMutationState<
getResult(mutationCache, options),
)
if (result !== nextResult) {
Object.assign(result, nextResult)
result.splice(0, result.length, ...nextResult)
}
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,54 @@ describe('useMutationState', () => {
expect(rendered.getByText('Data: ["success"]')).toBeInTheDocument()
})
})

describe('useMutationState - array shrinks when mutations no longer match filter', () => {
let queryClient: QueryClient

beforeEach(() => {
vi.useFakeTimers()
queryClient = new QueryClient()
})

afterEach(() => {
queryClient.clear()
vi.useRealTimers()
})

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)

// Both mutations settled — zero now match status: 'pending'
// Previously Object.assign never shrank the array so this stayed ["pending","pending"]
expect(rendered.getByText('Data: []')).toBeInTheDocument()
})
})