@tanstack/query-core 4.22.0 → 4.24.2

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.22.0",
3
+ "version": "4.24.2",
4
4
  "description": "The framework agnostic core that powers TanStack Query",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -28,9 +28,11 @@
28
28
  "src"
29
29
  ],
30
30
  "scripts": {
31
- "clean": "rm -rf ./build",
32
- "test:eslint": "../../node_modules/.bin/eslint --ext .ts,.tsx ./src",
33
- "test:jest": "../../node_modules/.bin/jest --config ./jest.config.ts",
34
- "test:dev": "pnpm run test:jest --watch"
31
+ "clean": "rimraf ./build",
32
+ "test:eslint": "eslint --ext .ts,.tsx ./src",
33
+ "test:types": "tsc",
34
+ "test:lib": "jest --config ./jest.config.ts",
35
+ "test:lib:dev": "pnpm run test:lib --watch",
36
+ "build:types": "tsc --build"
35
37
  }
36
38
  }
@@ -166,7 +166,7 @@ export class MutationObserver<
166
166
  private notify(options: NotifyOptions) {
167
167
  notifyManager.batch(() => {
168
168
  // First trigger the mutate callbacks
169
- if (this.mutateOptions) {
169
+ if (this.mutateOptions && this.hasListeners()) {
170
170
  if (options.onSuccess) {
171
171
  this.mutateOptions.onSuccess?.(
172
172
  this.currentResult.data!,
package/src/query.ts CHANGED
@@ -173,6 +173,7 @@ export class Query<
173
173
  this.queryHash = config.queryHash
174
174
  this.initialState = config.state || getDefaultState(this.options)
175
175
  this.state = this.initialState
176
+ this.scheduleGc()
176
177
  }
177
178
 
178
179
  get meta(): QueryMeta | undefined {
@@ -308,49 +308,24 @@ describe('mutations', () => {
308
308
  expect(onSettled).toHaveBeenCalled()
309
309
  })
310
310
 
311
- test('setState should update the mutation state', async () => {
312
- const mutation = new MutationObserver(queryClient, {
313
- mutationFn: async () => {
314
- return 'update'
315
- },
316
- onMutate: (text) => text,
317
- })
318
- await mutation.mutate()
319
- expect(mutation.getCurrentResult().data).toEqual('update')
320
-
321
- // Force setState usage
322
- // because no use case has been found using mutation.setState
323
- const currentMutation = mutation['currentMutation']
324
- currentMutation?.setState({
325
- context: undefined,
326
- variables: undefined,
327
- data: 'new',
328
- error: undefined,
329
- failureCount: 0,
330
- failureReason: null,
331
- isPaused: false,
332
- status: 'success',
333
- })
311
+ test('addObserver should not add an existing observer', async () => {
312
+ const mutationCache = queryClient.getMutationCache()
313
+ const observer = new MutationObserver(queryClient, {})
314
+ const currentMutation = mutationCache.build(queryClient, {})
334
315
 
335
- expect(mutation.getCurrentResult().data).toEqual('new')
336
- })
316
+ const fn = jest.fn()
337
317
 
338
- test('addObserver should not add an existing observer', async () => {
339
- const mutation = new MutationObserver(queryClient, {
340
- mutationFn: async () => {
341
- return 'update'
342
- },
343
- onMutate: (text) => text,
318
+ const unsubscribe = mutationCache.subscribe((event) => {
319
+ fn(event.type)
344
320
  })
345
- await mutation.mutate()
346
321
 
347
- // Force addObserver usage to add an existing observer
348
- // because no use case has been found
349
- const currentMutation = mutation['currentMutation']!
350
- expect(currentMutation['observers'].length).toEqual(1)
351
- currentMutation.addObserver(mutation)
322
+ currentMutation.addObserver(observer)
323
+ currentMutation.addObserver(observer)
352
324
 
353
- expect(currentMutation['observers'].length).toEqual(1)
325
+ expect(fn).toHaveBeenCalledTimes(1)
326
+ expect(fn).toHaveBeenCalledWith('observerAdded')
327
+
328
+ unsubscribe()
354
329
  })
355
330
 
356
331
  test('mutate should throw an error if no mutationFn found', async () => {
@@ -367,4 +342,20 @@ describe('mutations', () => {
367
342
  }
368
343
  expect(error).toEqual('No mutationFn found')
369
344
  })
345
+
346
+ test('mutate update the mutation state even without an active subscription', async () => {
347
+ const onSuccess = jest.fn()
348
+ const onSettled = jest.fn()
349
+
350
+ const mutation = new MutationObserver(queryClient, {
351
+ mutationFn: async () => {
352
+ return 'update'
353
+ },
354
+ })
355
+
356
+ await mutation.mutate(undefined, { onSuccess, onSettled })
357
+ expect(mutation.getCurrentResult().data).toEqual('update')
358
+ expect(onSuccess).not.toHaveBeenCalled()
359
+ expect(onSettled).not.toHaveBeenCalled()
360
+ })
370
361
  })
@@ -883,4 +883,28 @@ describe('query', () => {
883
883
 
884
884
  expect(initialDataUpdatedAtSpy).toHaveBeenCalled()
885
885
  })
886
+
887
+ test('queries should be garbage collected even if they never fetched', async () => {
888
+ const key = queryKey()
889
+
890
+ queryClient.setQueryDefaults(key, { cacheTime: 10 })
891
+
892
+ const fn = jest.fn()
893
+
894
+ const unsubscribe = queryClient.getQueryCache().subscribe(fn)
895
+
896
+ queryClient.setQueryData(key, 'data')
897
+
898
+ await waitFor(() =>
899
+ expect(fn).toHaveBeenCalledWith(
900
+ expect.objectContaining({
901
+ type: 'removed',
902
+ }),
903
+ ),
904
+ )
905
+
906
+ expect(queryClient.getQueryCache().findAll()).toHaveLength(0)
907
+
908
+ unsubscribe()
909
+ })
886
910
  })