diff --git a/docs/svelte/reactivity.md b/docs/svelte/reactivity.md
index 6d7b3fdc33..c4c8a105f9 100644
--- a/docs/svelte/reactivity.md
+++ b/docs/svelte/reactivity.md
@@ -3,7 +3,7 @@ id: reactivity
title: Reactivity
---
-Svelte uses a compiler to build your code which optimises rendering. By default, variables will run once, unless they are referenced in your markup. To be able to react to changes in options you need to use [stores](https://svelte.dev/tutorial/writable-stores).
+Svelte uses a compiler to build your code which optimises rendering. By default, variables will run once, unless they are referenced in your markup. To be able to react to changes in options you need to use [stores](https://svelte.dev/docs/svelte-store).
In the below example, the `refetchInterval` option is set from the variable `intervalMs`, which is edited by the input field. However, as the query is not told it should react to changes in `intervalMs`, `refetchInterval` will not change when the input value changes.
@@ -30,6 +30,7 @@ To solve this, create a store for the options and use it as input for the query.
```markdown
-
+
```
diff --git a/packages/svelte-query/src/__tests__/createQuery.test.ts b/packages/svelte-query/src/__tests__/createQuery.test.ts
index 47460e3d06..47be18395d 100644
--- a/packages/svelte-query/src/__tests__/createQuery.test.ts
+++ b/packages/svelte-query/src/__tests__/createQuery.test.ts
@@ -1,12 +1,12 @@
-import { describe, it, expect } from 'vitest'
+import { describe, expect, test } from 'vitest'
import { render, waitFor } from '@testing-library/svelte'
-import { writable } from 'svelte/store'
+import { derived, writable } from 'svelte/store'
import CreateQuery from './CreateQuery.svelte'
import { sleep } from './utils'
import type { CreateQueryOptions } from '../types'
describe('createQuery', () => {
- it('Render and wait for success', async () => {
+ test('Render and wait for success', async () => {
const rendered = render(CreateQuery, {
props: {
options: {
@@ -28,8 +28,8 @@ describe('createQuery', () => {
})
})
- it('should keep previous data when returned as placeholder data', async () => {
- const options: CreateQueryOptions = writable({
+ test('Keep previous data when returned as placeholder data', async () => {
+ const options = writable({
queryKey: ['test', [1]],
queryFn: async ({ queryKey }) => {
await sleep(10)
@@ -38,7 +38,8 @@ describe('createQuery', () => {
return ids.map((id) => ({ id }))
},
placeholderData: (previousData: { id: number }[]) => previousData,
- })
+ }) satisfies CreateQueryOptions
+
const rendered = render(CreateQuery, { props: { options } })
await waitFor(() => {
@@ -63,4 +64,46 @@ describe('createQuery', () => {
expect(rendered.queryByText('id: 2')).toBeInTheDocument()
})
})
+
+ test('Accept a writable store for options', async () => {
+ const optionsStore = writable({
+ queryKey: ['test'],
+ queryFn: async () => {
+ await sleep(10)
+ return 'Success'
+ },
+ }) satisfies CreateQueryOptions
+
+ const rendered = render(CreateQuery, {
+ props: {
+ options: optionsStore,
+ },
+ })
+
+ await waitFor(() => {
+ expect(rendered.getByText('Success')).toBeInTheDocument()
+ })
+ })
+
+ test('Accept a derived store for options', async () => {
+ const writableStore = writable('test')
+
+ const derivedStore = derived(writableStore, ($store) => ({
+ queryKey: [$store],
+ queryFn: async () => {
+ await sleep(10)
+ return 'Success'
+ },
+ })) satisfies CreateQueryOptions
+
+ const rendered = render(CreateQuery, {
+ props: {
+ options: derivedStore,
+ },
+ })
+
+ await waitFor(() => {
+ expect(rendered.getByText('Success')).toBeInTheDocument()
+ })
+ })
})
diff --git a/packages/svelte-query/src/createBaseQuery.ts b/packages/svelte-query/src/createBaseQuery.ts
index 0a23085284..a14322e32d 100644
--- a/packages/svelte-query/src/createBaseQuery.ts
+++ b/packages/svelte-query/src/createBaseQuery.ts
@@ -1,9 +1,9 @@
-import { derived, get, readable, writable } from 'svelte/store'
+import { derived, get, readable } from 'svelte/store'
import { notifyManager } from '@tanstack/query-core'
import type { QueryClient, QueryKey, QueryObserver } from '@tanstack/query-core'
import type { CreateBaseQueryOptions, CreateBaseQueryResult } from './types'
import { useQueryClient } from './useQueryClient'
-import { isWritable } from './utils'
+import { isSvelteStore } from './utils'
export function createBaseQuery<
TQueryFnData,
@@ -24,7 +24,7 @@ export function createBaseQuery<
): CreateBaseQueryResult {
const client = useQueryClient(queryClient)
- const optionsStore = isWritable(options) ? options : writable(options)
+ const optionsStore = isSvelteStore(options) ? options : readable(options)
const defaultedOptionsStore = derived(optionsStore, ($options) => {
const defaultedOptions = client.defaultQueryOptions($options)
diff --git a/packages/svelte-query/src/createMutation.ts b/packages/svelte-query/src/createMutation.ts
index 58004ea29a..cd12e1eff8 100644
--- a/packages/svelte-query/src/createMutation.ts
+++ b/packages/svelte-query/src/createMutation.ts
@@ -1,4 +1,4 @@
-import { readable, derived, writable, get } from 'svelte/store'
+import { readable, derived, get } from 'svelte/store'
import type { QueryClient, DefaultError } from '@tanstack/query-core'
import { MutationObserver, notifyManager } from '@tanstack/query-core'
import type {
@@ -7,7 +7,7 @@ import type {
CreateMutationResult,
} from './types'
import { useQueryClient } from './useQueryClient'
-import { isWritable } from './utils'
+import { isSvelteStore } from './utils'
export function createMutation<
TData = unknown,
@@ -20,7 +20,7 @@ export function createMutation<
): CreateMutationResult {
const client = useQueryClient(queryClient)
- const optionsStore = isWritable(options) ? options : writable(options)
+ const optionsStore = isSvelteStore(options) ? options : readable(options)
const observer = new MutationObserver(
client,
diff --git a/packages/svelte-query/src/createQueries.ts b/packages/svelte-query/src/createQueries.ts
index 7d8c7c3169..203e6d81ee 100644
--- a/packages/svelte-query/src/createQueries.ts
+++ b/packages/svelte-query/src/createQueries.ts
@@ -9,10 +9,11 @@ import type {
QueryObserverOptions,
} from '@tanstack/query-core'
import { notifyManager, QueriesObserver } from '@tanstack/query-core'
-import { derived, get, readable, writable, type Readable } from 'svelte/store'
-import type { WritableOrVal } from './types'
+import { derived, get, readable } from 'svelte/store'
+import type { Readable } from 'svelte/store'
+import type { StoreOrVal } from './types'
import { useQueryClient } from './useQueryClient'
-import { isWritable } from './utils'
+import { isSvelteStore } from './utils'
// This defines the `CreateQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.
// `placeholderData` function does not have a parameter
@@ -168,7 +169,7 @@ export function createQueries<
queries,
...options
}: {
- queries: WritableOrVal<[...QueriesOptions]>
+ queries: StoreOrVal<[...QueriesOptions]>
combine?: (result: QueriesResults) => TCombinedResult
},
queryClient?: QueryClient,
@@ -176,7 +177,7 @@ export function createQueries<
const client = useQueryClient(queryClient)
// const isRestoring = useIsRestoring()
- const queriesStore = isWritable(queries) ? queries : writable(queries)
+ const queriesStore = isSvelteStore(queries) ? queries : readable(queries)
const defaultedQueriesStore = derived(queriesStore, ($queries) => {
return $queries.map((opts) => {
diff --git a/packages/svelte-query/src/types.ts b/packages/svelte-query/src/types.ts
index 39a058586e..3e9f6d6351 100644
--- a/packages/svelte-query/src/types.ts
+++ b/packages/svelte-query/src/types.ts
@@ -13,7 +13,7 @@ import type {
import type { Readable, Writable } from 'svelte/store'
/** Allows a type to be either the base object or a store of that object */
-export type WritableOrVal = T | Writable
+export type StoreOrVal = T | Readable | Writable
/** Options for createBaseQuery */
export type CreateBaseQueryOptions<
@@ -22,7 +22,7 @@ export type CreateBaseQueryOptions<
TData = TQueryFnData,
TQueryData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
-> = WritableOrVal<
+> = StoreOrVal<
QueryObserverOptions
>
@@ -54,7 +54,7 @@ export type CreateInfiniteQueryOptions<
TQueryData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
TPageParam = unknown,
-> = WritableOrVal<
+> = StoreOrVal<
InfiniteQueryObserverOptions<
TQueryFnData,
TError,
@@ -89,7 +89,7 @@ export type CreateMutationOptions<
TError = DefaultError,
TVariables = void,
TContext = unknown,
-> = WritableOrVal<
+> = StoreOrVal<
Omit<
MutationObserverOptions,
'_defaulted' | 'variables'
diff --git a/packages/svelte-query/src/useIsFetching.ts b/packages/svelte-query/src/useIsFetching.ts
index 86d5e2b23f..c6089b76b1 100644
--- a/packages/svelte-query/src/useIsFetching.ts
+++ b/packages/svelte-query/src/useIsFetching.ts
@@ -3,7 +3,8 @@ import {
type QueryClient,
notifyManager,
} from '@tanstack/query-core'
-import { type Readable, readable } from 'svelte/store'
+import { readable } from 'svelte/store'
+import type { Readable } from 'svelte/store'
import { useQueryClient } from './useQueryClient'
export function useIsFetching(
diff --git a/packages/svelte-query/src/useIsMutating.ts b/packages/svelte-query/src/useIsMutating.ts
index c4293fa744..4aa231c873 100644
--- a/packages/svelte-query/src/useIsMutating.ts
+++ b/packages/svelte-query/src/useIsMutating.ts
@@ -3,7 +3,8 @@ import {
type QueryClient,
notifyManager,
} from '@tanstack/query-core'
-import { type Readable, readable } from 'svelte/store'
+import { readable } from 'svelte/store'
+import type { Readable } from 'svelte/store'
import { useQueryClient } from './useQueryClient'
export function useIsMutating(
diff --git a/packages/svelte-query/src/utils.ts b/packages/svelte-query/src/utils.ts
index 8ce19a7f43..eb86225694 100644
--- a/packages/svelte-query/src/utils.ts
+++ b/packages/svelte-query/src/utils.ts
@@ -1,8 +1,8 @@
-import type { Writable } from 'svelte/store'
-import type { WritableOrVal } from './types'
+import type { Readable } from 'svelte/store'
+import type { StoreOrVal } from './types'
-export function isWritable(
- obj: WritableOrVal,
-): obj is Writable {
- return 'subscribe' in obj && 'set' in obj && 'update' in obj
+export function isSvelteStore(
+ obj: StoreOrVal,
+): obj is Readable {
+ return 'subscribe' in obj && typeof obj.subscribe === 'function'
}
diff --git a/packages/svelte-query/vitest.setup.ts b/packages/svelte-query/vitest.setup.ts
index d263e51f4f..7f489d28ba 100644
--- a/packages/svelte-query/vitest.setup.ts
+++ b/packages/svelte-query/vitest.setup.ts
@@ -1,4 +1,7 @@
import matchers from '@testing-library/jest-dom/matchers'
-import { expect } from 'vitest'
+import { cleanup } from '@testing-library/svelte'
+import { afterEach, expect } from 'vitest'
expect.extend(matchers)
+
+afterEach(() => cleanup())