@tanstack/query-core 4.1.2 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/query-core",
3
- "version": "4.1.2",
3
+ "version": "4.2.1",
4
4
  "description": "TODO",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -13,6 +13,7 @@ import {
13
13
  QueryClient,
14
14
  QueryFunction,
15
15
  QueryObserver,
16
+ QueryObserverOptions,
16
17
  } from '..'
17
18
  import { focusManager, onlineManager } from '..'
18
19
 
@@ -357,6 +358,38 @@ describe('queryClient', () => {
357
358
  expect(queryCache.find(key)!.state.data).toBe(newData)
358
359
  })
359
360
 
361
+ test('should apply a custom structuralSharing function when provided', () => {
362
+ const key = queryKey()
363
+
364
+ const queryObserverOptions = {
365
+ structuralSharing: (
366
+ prevData: { value: Date } | undefined,
367
+ newData: { value: Date },
368
+ ) => {
369
+ if (!prevData) {
370
+ return newData
371
+ }
372
+ return newData.value.getTime() === prevData.value.getTime()
373
+ ? prevData
374
+ : newData
375
+ },
376
+ } as QueryObserverOptions
377
+
378
+ queryClient.setDefaultOptions({ queries: queryObserverOptions })
379
+
380
+ const oldData = { value: new Date(2022, 6, 19) }
381
+ const newData = { value: new Date(2022, 6, 19) }
382
+ queryClient.setQueryData(key, oldData)
383
+ queryClient.setQueryData(key, newData)
384
+
385
+ expect(queryCache.find(key)!.state.data).toBe(oldData)
386
+
387
+ const distinctData = { value: new Date(2021, 11, 25) }
388
+ queryClient.setQueryData(key, distinctData)
389
+
390
+ expect(queryCache.find(key)!.state.data).toBe(distinctData)
391
+ })
392
+
360
393
  test('should not set isFetching to false', async () => {
361
394
  const key = queryKey()
362
395
  queryClient.prefetchQuery(key, async () => {
package/src/types.ts CHANGED
@@ -76,9 +76,12 @@ export interface QueryOptions<
76
76
  behavior?: QueryBehavior<TQueryFnData, TError, TData>
77
77
  /**
78
78
  * Set this to `false` to disable structural sharing between query results.
79
+ * Set this to a function which accepts the old and new data and returns resolved data of the same type to implement custom structural sharing logic.
79
80
  * Defaults to `true`.
80
81
  */
81
- structuralSharing?: boolean
82
+ structuralSharing?:
83
+ | boolean
84
+ | ((oldData: TData | undefined, newData: TData) => TData)
82
85
  /**
83
86
  * This function can be set to automatically get the previous cursor for infinite queries.
84
87
  * The result will also be used to determine the value of `hasPreviousPage`.
@@ -425,11 +428,14 @@ export interface QueryObserverSuccessResult<TData = unknown, TError = unknown>
425
428
  status: 'success'
426
429
  }
427
430
 
431
+ export type DefinedQueryObserverResult<TData = unknown, TError = unknown> =
432
+ | QueryObserverRefetchErrorResult<TData, TError>
433
+ | QueryObserverSuccessResult<TData, TError>
434
+
428
435
  export type QueryObserverResult<TData = unknown, TError = unknown> =
436
+ | DefinedQueryObserverResult<TData, TError>
429
437
  | QueryObserverLoadingErrorResult<TData, TError>
430
438
  | QueryObserverLoadingResult<TData, TError>
431
- | QueryObserverRefetchErrorResult<TData, TError>
432
- | QueryObserverSuccessResult<TData, TError>
433
439
 
434
440
  export interface InfiniteQueryObserverBaseResult<
435
441
  TData = unknown,
package/src/utils.ts CHANGED
@@ -427,6 +427,8 @@ export function replaceData<
427
427
  // Use prev data if an isDataEqual function is defined and returns `true`
428
428
  if (options.isDataEqual?.(prevData, data)) {
429
429
  return prevData as TData
430
+ } else if (typeof options.structuralSharing === 'function') {
431
+ return options.structuralSharing(prevData, data)
430
432
  } else if (options.structuralSharing !== false) {
431
433
  // Structurally share data between prev and new data if needed
432
434
  return replaceEqualDeep(prevData, data)