@tanstack/vue-query
Advanced tools
Comparing version 5.50.1 to 5.51.0
@@ -9,2 +9,3 @@ // src/useQueries.ts | ||
shallowRef, | ||
unref, | ||
watch | ||
@@ -26,14 +27,14 @@ } from "vue-demi"; | ||
const client = queryClient || useQueryClient(); | ||
const defaultedQueries = computed( | ||
() => cloneDeepUnref(queries).map( | ||
(queryOptions) => { | ||
if (typeof queryOptions.enabled === "function") { | ||
queryOptions.enabled = queryOptions.enabled(); | ||
} | ||
const defaulted = client.defaultQueryOptions(queryOptions); | ||
defaulted._optimisticResults = client.isRestoring.value ? "isRestoring" : "optimistic"; | ||
return defaulted; | ||
const defaultedQueries = computed(() => { | ||
const queriesRaw = unref(queries); | ||
return queriesRaw.map((queryOptions) => { | ||
const clonedOptions = cloneDeepUnref(queryOptions); | ||
if (typeof clonedOptions.enabled === "function") { | ||
clonedOptions.enabled = queryOptions.enabled(); | ||
} | ||
) | ||
); | ||
const defaulted = client.defaultQueryOptions(clonedOptions); | ||
defaulted._optimisticResults = client.isRestoring.value ? "isRestoring" : "optimistic"; | ||
return defaulted; | ||
}); | ||
}); | ||
const observer = new QueriesObserver( | ||
@@ -40,0 +41,0 @@ client, |
@@ -7,6 +7,6 @@ import { MaybeRefDeep } from './types.js'; | ||
declare function updateState(state: Record<string, unknown>, update: Record<string, any>): void; | ||
declare function cloneDeep<T>(value: MaybeRefDeep<T>, customize?: (val: MaybeRefDeep<T>) => T | undefined): T; | ||
declare function cloneDeepUnref<T>(obj: MaybeRefDeep<T>): T; | ||
declare function cloneDeep<T>(value: MaybeRefDeep<T>, customize?: (val: MaybeRefDeep<T>, key: string, level: number) => T | undefined): T; | ||
declare function cloneDeepUnref<T>(obj: MaybeRefDeep<T>, unrefGetters?: boolean): T; | ||
declare function shouldThrowError<T extends (...args: Array<any>) => boolean>(throwOnError: boolean | T | undefined, params: Parameters<T>): boolean; | ||
export { VUE_QUERY_CLIENT, cloneDeep, cloneDeepUnref, getClientKey, shouldThrowError, updateState }; |
@@ -13,5 +13,5 @@ // src/utils.ts | ||
} | ||
function cloneDeep(value, customize) { | ||
function _cloneDeep(value, customize, currentKey = "", currentLevel = 0) { | ||
if (customize) { | ||
const result = customize(value); | ||
const result = customize(value, currentKey, currentLevel); | ||
if (result === void 0 && isRef(value)) { | ||
@@ -25,3 +25,5 @@ return result; | ||
if (Array.isArray(value)) { | ||
return value.map((val) => cloneDeep(val, customize)); | ||
return value.map( | ||
(val, index) => _cloneDeep(val, customize, String(index), currentLevel + 1) | ||
); | ||
} | ||
@@ -31,3 +33,3 @@ if (typeof value === "object" && isPlainObject(value)) { | ||
key, | ||
cloneDeep(val, customize) | ||
_cloneDeep(val, customize, key, currentLevel + 1) | ||
]); | ||
@@ -38,6 +40,15 @@ return Object.fromEntries(entries); | ||
} | ||
function cloneDeepUnref(obj) { | ||
return cloneDeep(obj, (val) => { | ||
function cloneDeep(value, customize) { | ||
return _cloneDeep(value, customize); | ||
} | ||
function cloneDeepUnref(obj, unrefGetters = false) { | ||
return cloneDeep(obj, (val, key, level) => { | ||
if (level === 1 && key === "queryKey") { | ||
return cloneDeepUnref(val, true); | ||
} | ||
if (unrefGetters && isFunction(val)) { | ||
return cloneDeepUnref(val(), unrefGetters); | ||
} | ||
if (isRef(val)) { | ||
return cloneDeepUnref(unref(val)); | ||
return cloneDeepUnref(unref(val), unrefGetters); | ||
} | ||
@@ -54,2 +65,5 @@ return void 0; | ||
} | ||
function isFunction(value) { | ||
return typeof value === "function"; | ||
} | ||
function shouldThrowError(throwOnError, params) { | ||
@@ -56,0 +70,0 @@ if (typeof throwOnError === "function") { |
@@ -9,2 +9,3 @@ // src/useQueries.ts | ||
shallowRef, | ||
unref, | ||
watch | ||
@@ -26,14 +27,14 @@ } from "vue-demi"; | ||
const client = queryClient || useQueryClient(); | ||
const defaultedQueries = computed( | ||
() => cloneDeepUnref(queries).map( | ||
(queryOptions) => { | ||
if (typeof queryOptions.enabled === "function") { | ||
queryOptions.enabled = queryOptions.enabled(); | ||
} | ||
const defaulted = client.defaultQueryOptions(queryOptions); | ||
defaulted._optimisticResults = client.isRestoring.value ? "isRestoring" : "optimistic"; | ||
return defaulted; | ||
const defaultedQueries = computed(() => { | ||
const queriesRaw = unref(queries); | ||
return queriesRaw.map((queryOptions) => { | ||
const clonedOptions = cloneDeepUnref(queryOptions); | ||
if (typeof clonedOptions.enabled === "function") { | ||
clonedOptions.enabled = queryOptions.enabled(); | ||
} | ||
) | ||
); | ||
const defaulted = client.defaultQueryOptions(clonedOptions); | ||
defaulted._optimisticResults = client.isRestoring.value ? "isRestoring" : "optimistic"; | ||
return defaulted; | ||
}); | ||
}); | ||
const observer = new QueriesObserver( | ||
@@ -40,0 +41,0 @@ client, |
@@ -7,6 +7,6 @@ import { MaybeRefDeep } from './types.js'; | ||
declare function updateState(state: Record<string, unknown>, update: Record<string, any>): void; | ||
declare function cloneDeep<T>(value: MaybeRefDeep<T>, customize?: (val: MaybeRefDeep<T>) => T | undefined): T; | ||
declare function cloneDeepUnref<T>(obj: MaybeRefDeep<T>): T; | ||
declare function cloneDeep<T>(value: MaybeRefDeep<T>, customize?: (val: MaybeRefDeep<T>, key: string, level: number) => T | undefined): T; | ||
declare function cloneDeepUnref<T>(obj: MaybeRefDeep<T>, unrefGetters?: boolean): T; | ||
declare function shouldThrowError<T extends (...args: Array<any>) => boolean>(throwOnError: boolean | T | undefined, params: Parameters<T>): boolean; | ||
export { VUE_QUERY_CLIENT, cloneDeep, cloneDeepUnref, getClientKey, shouldThrowError, updateState }; |
@@ -13,5 +13,5 @@ // src/utils.ts | ||
} | ||
function cloneDeep(value, customize) { | ||
function _cloneDeep(value, customize, currentKey = "", currentLevel = 0) { | ||
if (customize) { | ||
const result = customize(value); | ||
const result = customize(value, currentKey, currentLevel); | ||
if (result === void 0 && isRef(value)) { | ||
@@ -25,3 +25,5 @@ return result; | ||
if (Array.isArray(value)) { | ||
return value.map((val) => cloneDeep(val, customize)); | ||
return value.map( | ||
(val, index) => _cloneDeep(val, customize, String(index), currentLevel + 1) | ||
); | ||
} | ||
@@ -31,3 +33,3 @@ if (typeof value === "object" && isPlainObject(value)) { | ||
key, | ||
cloneDeep(val, customize) | ||
_cloneDeep(val, customize, key, currentLevel + 1) | ||
]); | ||
@@ -38,6 +40,15 @@ return Object.fromEntries(entries); | ||
} | ||
function cloneDeepUnref(obj) { | ||
return cloneDeep(obj, (val) => { | ||
function cloneDeep(value, customize) { | ||
return _cloneDeep(value, customize); | ||
} | ||
function cloneDeepUnref(obj, unrefGetters = false) { | ||
return cloneDeep(obj, (val, key, level) => { | ||
if (level === 1 && key === "queryKey") { | ||
return cloneDeepUnref(val, true); | ||
} | ||
if (unrefGetters && isFunction(val)) { | ||
return cloneDeepUnref(val(), unrefGetters); | ||
} | ||
if (isRef(val)) { | ||
return cloneDeepUnref(unref(val)); | ||
return cloneDeepUnref(unref(val), unrefGetters); | ||
} | ||
@@ -54,2 +65,5 @@ return void 0; | ||
} | ||
function isFunction(value) { | ||
return typeof value === "function"; | ||
} | ||
function shouldThrowError(throwOnError, params) { | ||
@@ -56,0 +70,0 @@ if (typeof throwOnError === "function") { |
{ | ||
"name": "@tanstack/vue-query", | ||
"version": "5.50.1", | ||
"version": "5.51.0", | ||
"description": "Hooks for managing, caching and syncing asynchronous and remote data in Vue", | ||
@@ -5,0 +5,0 @@ "author": "Damian Osipiuk", |
@@ -278,2 +278,94 @@ import { beforeEach, describe, expect, test, vi } from 'vitest' | ||
}) | ||
test('should allow getters for query keys', async () => { | ||
const fetchFn = vi.fn() | ||
const key1 = ref('key1') | ||
const key2 = ref('key2') | ||
useQueries({ | ||
queries: [ | ||
{ | ||
queryKey: ['key', () => key1.value, () => key2.value], | ||
queryFn: fetchFn, | ||
}, | ||
], | ||
}) | ||
expect(fetchFn).toHaveBeenCalledTimes(1) | ||
key1.value = 'key3' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(2) | ||
key2.value = 'key4' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(3) | ||
}) | ||
test('should allow arbitrarily nested getters for query keys', async () => { | ||
const fetchFn = vi.fn() | ||
const key1 = ref('key1') | ||
const key2 = ref('key2') | ||
const key3 = ref('key3') | ||
const key4 = ref('key4') | ||
const key5 = ref('key5') | ||
useQueries({ | ||
queries: [ | ||
{ | ||
queryKey: [ | ||
'key', | ||
key1, | ||
() => key2.value, | ||
{ key: () => key3.value }, | ||
[{ foo: { bar: () => key4.value } }], | ||
() => ({ | ||
foo: { | ||
bar: { | ||
baz: () => key5.value, | ||
}, | ||
}, | ||
}), | ||
], | ||
queryFn: fetchFn, | ||
}, | ||
], | ||
}) | ||
expect(fetchFn).toHaveBeenCalledTimes(1) | ||
key1.value = 'key1-updated' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(2) | ||
key2.value = 'key2-updated' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(3) | ||
key3.value = 'key3-updated' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(4) | ||
key4.value = 'key4-updated' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(5) | ||
key5.value = 'key5-updated' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(6) | ||
}) | ||
}) |
@@ -290,2 +290,86 @@ import { describe, expect, test, vi } from 'vitest' | ||
test('should allow getters for query keys', async () => { | ||
const fetchFn = vi.fn() | ||
const key1 = ref('key1') | ||
const key2 = ref('key2') | ||
useQuery({ | ||
queryKey: ['key', () => key1.value, () => key2.value], | ||
queryFn: fetchFn, | ||
}) | ||
expect(fetchFn).toHaveBeenCalledTimes(1) | ||
key1.value = 'key3' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(2) | ||
key2.value = 'key4' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(3) | ||
}) | ||
test('should allow arbitrarily nested getters for query keys', async () => { | ||
const fetchFn = vi.fn() | ||
const key1 = ref('key1') | ||
const key2 = ref('key2') | ||
const key3 = ref('key3') | ||
const key4 = ref('key4') | ||
const key5 = ref('key5') | ||
useQuery({ | ||
queryKey: [ | ||
'key', | ||
key1, | ||
() => key2.value, | ||
{ key: () => key3.value }, | ||
[{ foo: { bar: () => key4.value } }], | ||
() => ({ | ||
foo: { | ||
bar: { | ||
baz: () => key5.value, | ||
}, | ||
}, | ||
}), | ||
], | ||
queryFn: fetchFn, | ||
}) | ||
expect(fetchFn).toHaveBeenCalledTimes(1) | ||
key1.value = 'key1-updated' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(2) | ||
key2.value = 'key2-updated' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(3) | ||
key3.value = 'key3-updated' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(4) | ||
key4.value = 'key4-updated' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(5) | ||
key5.value = 'key5-updated' | ||
await flushPromises() | ||
expect(fetchFn).toHaveBeenCalledTimes(6) | ||
}) | ||
describe('throwOnError', () => { | ||
@@ -292,0 +376,0 @@ test('should evaluate throwOnError when query is expected to throw', async () => { |
@@ -8,2 +8,3 @@ import { QueriesObserver } from '@tanstack/query-core' | ||
shallowRef, | ||
unref, | ||
watch, | ||
@@ -272,19 +273,23 @@ } from 'vue-demi' | ||
const defaultedQueries = computed(() => | ||
cloneDeepUnref(queries as MaybeRefDeep<UseQueriesOptionsArg<any>>).map( | ||
(queryOptions) => { | ||
if (typeof queryOptions.enabled === 'function') { | ||
queryOptions.enabled = queryOptions.enabled() | ||
} | ||
const defaultedQueries = computed(() => { | ||
// Only unref the top level array. | ||
const queriesRaw = unref(queries) as ReadonlyArray<any> | ||
const defaulted = client.defaultQueryOptions(queryOptions) | ||
defaulted._optimisticResults = client.isRestoring.value | ||
? 'isRestoring' | ||
: 'optimistic' | ||
// Unref the rest for each element in the top level array. | ||
return queriesRaw.map((queryOptions) => { | ||
const clonedOptions = cloneDeepUnref(queryOptions) | ||
return defaulted | ||
}, | ||
), | ||
) | ||
if (typeof clonedOptions.enabled === 'function') { | ||
clonedOptions.enabled = queryOptions.enabled() | ||
} | ||
const defaulted = client.defaultQueryOptions(clonedOptions) | ||
defaulted._optimisticResults = client.isRestoring.value | ||
? 'isRestoring' | ||
: 'optimistic' | ||
return defaulted | ||
}) | ||
}) | ||
const observer = new QueriesObserver<TCombinedResult>( | ||
@@ -291,0 +296,0 @@ client, |
@@ -20,9 +20,16 @@ import { isRef, unref } from 'vue-demi' | ||
export function cloneDeep<T>( | ||
// Helper function for cloning deep objects where | ||
// the level and key is provided to the callback function. | ||
function _cloneDeep<T>( | ||
value: MaybeRefDeep<T>, | ||
customize?: (val: MaybeRefDeep<T>) => T | undefined, | ||
customize?: ( | ||
val: MaybeRefDeep<T>, | ||
key: string, | ||
level: number, | ||
) => T | undefined, | ||
currentKey: string = '', | ||
currentLevel: number = 0, | ||
): T { | ||
if (customize) { | ||
const result = customize(value) | ||
// If it's a ref of undefined, return undefined | ||
const result = customize(value, currentKey, currentLevel) | ||
if (result === undefined && isRef(value)) { | ||
@@ -37,3 +44,5 @@ return result as T | ||
if (Array.isArray(value)) { | ||
return value.map((val) => cloneDeep(val, customize)) as unknown as T | ||
return value.map((val, index) => | ||
_cloneDeep(val, customize, String(index), currentLevel + 1), | ||
) as unknown as T | ||
} | ||
@@ -44,3 +53,3 @@ | ||
key, | ||
cloneDeep(val, customize), | ||
_cloneDeep(val, customize, key, currentLevel + 1), | ||
]) | ||
@@ -53,6 +62,36 @@ return Object.fromEntries(entries) | ||
export function cloneDeepUnref<T>(obj: MaybeRefDeep<T>): T { | ||
return cloneDeep(obj, (val) => { | ||
export function cloneDeep<T>( | ||
value: MaybeRefDeep<T>, | ||
customize?: ( | ||
val: MaybeRefDeep<T>, | ||
key: string, | ||
level: number, | ||
) => T | undefined, | ||
): T { | ||
return _cloneDeep(value, customize) | ||
} | ||
export function cloneDeepUnref<T>( | ||
obj: MaybeRefDeep<T>, | ||
unrefGetters = false, | ||
): T { | ||
return cloneDeep(obj, (val, key, level) => { | ||
// Check if we're at the top level and the key is 'queryKey' | ||
// | ||
// If so, take the recursive descent where we resolve | ||
// getters to values as well as refs. | ||
if (level === 1 && key === 'queryKey') { | ||
return cloneDeepUnref(val, true) | ||
} | ||
// Resolve getters to values if specified. | ||
if (unrefGetters && isFunction(val)) { | ||
// Cast due to older TS versions not allowing calling | ||
// on certain intersection types. | ||
return cloneDeepUnref((val as Function)(), unrefGetters) | ||
} | ||
// Unref refs and continue to recurse into the value. | ||
if (isRef(val)) { | ||
return cloneDeepUnref(unref(val)) | ||
return cloneDeepUnref(unref(val), unrefGetters) | ||
} | ||
@@ -73,2 +112,6 @@ | ||
function isFunction(value: unknown): value is Function { | ||
return typeof value === 'function' | ||
} | ||
export function shouldThrowError<T extends (...args: Array<any>) => boolean>( | ||
@@ -75,0 +118,0 @@ throwOnError: boolean | T | undefined, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
791380
10832