@tanstack/angular-query-experimental 5.34.2 → 5.35.0

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.
Files changed (59) hide show
  1. package/build/rollup.d.ts +591 -0
  2. package/package.json +9 -5
  3. package/build/create-base-query.d.ts +0 -6
  4. package/build/index.d.ts +0 -14
  5. package/build/infinite-query-options.d.ts +0 -34
  6. package/build/inject-infinite-query.d.ts +0 -31
  7. package/build/inject-is-fetching.d.ts +0 -13
  8. package/build/inject-is-mutating.d.ts +0 -12
  9. package/build/inject-mutation-state.d.ts +0 -21
  10. package/build/inject-mutation.d.ts +0 -13
  11. package/build/inject-queries.d.ts +0 -76
  12. package/build/inject-query-client.d.ts +0 -30
  13. package/build/inject-query.d.ts +0 -106
  14. package/build/providers.d.ts +0 -42
  15. package/build/query-options.d.ts +0 -66
  16. package/build/signal-proxy.d.ts +0 -11
  17. package/build/types.d.ts +0 -95
  18. package/build/util/assert-injector/assert-injector.d.ts +0 -54
  19. package/build/util/create-injection-token/create-injection-token.d.ts +0 -52
  20. package/build/util/index.d.ts +0 -2
  21. package/build/util/lazy-init/lazy-init.d.ts +0 -1
  22. package/build/util/lazy-signal-initializer/lazy-signal-initializer.d.ts +0 -4
  23. package/src/__tests__/inject-infinite-query.test.ts +0 -64
  24. package/src/__tests__/inject-is-fetching.test.ts +0 -35
  25. package/src/__tests__/inject-is-mutating.test.ts +0 -39
  26. package/src/__tests__/inject-mutation-state.test-d.ts +0 -22
  27. package/src/__tests__/inject-mutation-state.test.ts +0 -175
  28. package/src/__tests__/inject-mutation.test-d.ts +0 -71
  29. package/src/__tests__/inject-mutation.test.ts +0 -458
  30. package/src/__tests__/inject-query.test-d.ts +0 -59
  31. package/src/__tests__/inject-query.test.ts +0 -349
  32. package/src/__tests__/query-options.test-d.ts +0 -127
  33. package/src/__tests__/signal-proxy.test.ts +0 -27
  34. package/src/__tests__/test-utils.ts +0 -131
  35. package/src/__tests__/util/lazy-init/lazy-init.test.ts +0 -126
  36. package/src/__tests__/util/lazy-signal-initializer/lazy-signal-initializer.test.ts +0 -130
  37. package/src/create-base-query.ts +0 -116
  38. package/src/index.ts +0 -24
  39. package/src/infinite-query-options.ts +0 -118
  40. package/src/inject-infinite-query.ts +0 -125
  41. package/src/inject-is-fetching.ts +0 -49
  42. package/src/inject-is-mutating.ts +0 -48
  43. package/src/inject-mutation-state.ts +0 -107
  44. package/src/inject-mutation.ts +0 -118
  45. package/src/inject-queries.ts +0 -265
  46. package/src/inject-query-client.ts +0 -25
  47. package/src/inject-query.ts +0 -200
  48. package/src/providers.ts +0 -65
  49. package/src/query-options.ts +0 -122
  50. package/src/signal-proxy.ts +0 -46
  51. package/src/test-setup.ts +0 -12
  52. package/src/types.ts +0 -311
  53. package/src/util/assert-injector/assert-injector.test.ts +0 -74
  54. package/src/util/assert-injector/assert-injector.ts +0 -81
  55. package/src/util/create-injection-token/create-injection-token.test.ts +0 -32
  56. package/src/util/create-injection-token/create-injection-token.ts +0 -185
  57. package/src/util/index.ts +0 -13
  58. package/src/util/lazy-init/lazy-init.ts +0 -34
  59. package/src/util/lazy-signal-initializer/lazy-signal-initializer.ts +0 -28
@@ -1,458 +0,0 @@
1
- import { Component, input, signal } from '@angular/core'
2
- import { QueryClient } from '@tanstack/query-core'
3
- import { TestBed } from '@angular/core/testing'
4
- import { describe, expect, vi } from 'vitest'
5
- import { By } from '@angular/platform-browser'
6
- import { injectMutation } from '../inject-mutation'
7
- import { provideAngularQuery } from '../providers'
8
- import {
9
- errorMutator,
10
- expectSignals,
11
- setFixtureSignalInputs,
12
- successMutator,
13
- } from './test-utils'
14
-
15
- const MUTATION_DURATION = 1000
16
-
17
- const resolveMutations = () => vi.advanceTimersByTimeAsync(MUTATION_DURATION)
18
-
19
- describe('injectMutation', () => {
20
- let queryClient: QueryClient
21
-
22
- beforeEach(() => {
23
- queryClient = new QueryClient()
24
- vi.useFakeTimers()
25
- TestBed.configureTestingModule({
26
- providers: [provideAngularQuery(queryClient)],
27
- })
28
- })
29
-
30
- afterEach(() => {
31
- vi.useRealTimers()
32
- })
33
-
34
- describe('callback helpers', () => {
35
- test('can access client from options callback', async () => {
36
- const mutation = TestBed.runInInjectionContext(() => {
37
- return injectMutation((client) => ({
38
- mutationFn: () => {
39
- expect(client).toBe(queryClient)
40
- return Promise.resolve()
41
- },
42
- }))
43
- })
44
-
45
- mutation.mutate()
46
- vi.advanceTimersByTime(1)
47
- expect(mutation.status()).toBe('pending')
48
- })
49
- })
50
-
51
- test('should be in idle state initially', () => {
52
- const mutation = TestBed.runInInjectionContext(() => {
53
- return injectMutation(() => ({
54
- mutationFn: (params) => successMutator(params),
55
- }))
56
- })
57
-
58
- expectSignals(mutation, {
59
- isIdle: true,
60
- isPending: false,
61
- isError: false,
62
- isSuccess: false,
63
- })
64
- })
65
-
66
- test('should change state after invoking mutate', async () => {
67
- const result = 'Mock data'
68
-
69
- const mutation = TestBed.runInInjectionContext(() => {
70
- return injectMutation(() => ({
71
- mutationFn: (params: string) => successMutator(params),
72
- }))
73
- })
74
-
75
- mutation.mutate(result)
76
- vi.advanceTimersByTime(1)
77
-
78
- expectSignals(mutation, {
79
- isIdle: false,
80
- isPending: true,
81
- isError: false,
82
- isSuccess: false,
83
- data: undefined,
84
- error: null,
85
- })
86
- })
87
-
88
- test('should return error when request fails', async () => {
89
- const mutation = TestBed.runInInjectionContext(() => {
90
- return injectMutation(() => ({
91
- mutationFn: errorMutator,
92
- }))
93
- })
94
- mutation.mutate({})
95
-
96
- await resolveMutations()
97
-
98
- expectSignals(mutation, {
99
- isIdle: false,
100
- isPending: false,
101
- isError: true,
102
- isSuccess: false,
103
- data: undefined,
104
- error: Error('Some error'),
105
- })
106
- })
107
-
108
- test('should return data when request succeeds', async () => {
109
- const result = 'Mock data'
110
- const mutation = TestBed.runInInjectionContext(() => {
111
- return injectMutation(() => ({
112
- mutationFn: (params: string) => successMutator(params),
113
- }))
114
- })
115
-
116
- mutation.mutate(result)
117
-
118
- await resolveMutations()
119
-
120
- expectSignals(mutation, {
121
- isIdle: false,
122
- isPending: false,
123
- isError: false,
124
- isSuccess: true,
125
- data: result,
126
- error: null,
127
- })
128
- })
129
-
130
- test('reactive options should update mutation', async () => {
131
- const mutationCache = queryClient.getMutationCache()
132
- // Signal will be updated before the mutation is called
133
- // this test confirms that the mutation uses the updated value
134
- const mutationKey = signal(['1'])
135
- const mutation = TestBed.runInInjectionContext(() => {
136
- return injectMutation(() => ({
137
- mutationKey: mutationKey(),
138
- mutationFn: (params: string) => successMutator(params),
139
- }))
140
- })
141
-
142
- mutationKey.set(['2'])
143
-
144
- TestBed.flushEffects()
145
-
146
- mutation.mutate('xyz')
147
-
148
- const mutations = mutationCache.find({ mutationKey: ['2'] })
149
-
150
- expect(mutations?.options.mutationKey).toEqual(['2'])
151
- })
152
-
153
- test('should reset state after invoking mutation.reset', async () => {
154
- const mutation = TestBed.runInInjectionContext(() => {
155
- return injectMutation(() => ({
156
- mutationFn: (params: string) => errorMutator(params),
157
- }))
158
- })
159
-
160
- mutation.mutate('')
161
-
162
- await resolveMutations()
163
-
164
- expect(mutation.isError()).toBe(true)
165
-
166
- mutation.reset()
167
-
168
- await resolveMutations()
169
-
170
- expectSignals(mutation, {
171
- isIdle: true,
172
- isPending: false,
173
- isError: false,
174
- isSuccess: false,
175
- data: undefined,
176
- error: null,
177
- })
178
- })
179
-
180
- describe('side effects', () => {
181
- beforeEach(() => {
182
- vi.clearAllMocks()
183
- })
184
-
185
- test('should call onMutate when passed as an option', async () => {
186
- const onMutate = vi.fn()
187
- const mutation = TestBed.runInInjectionContext(() => {
188
- return injectMutation(() => ({
189
- mutationFn: (params: string) => successMutator(params),
190
- onMutate,
191
- }))
192
- })
193
-
194
- mutation.mutate('')
195
-
196
- await resolveMutations()
197
-
198
- expect(onMutate).toHaveBeenCalledTimes(1)
199
- })
200
-
201
- test('should call onError when passed as an option', async () => {
202
- const onError = vi.fn()
203
- const mutation = TestBed.runInInjectionContext(() => {
204
- return injectMutation(() => ({
205
- mutationFn: (params: string) => errorMutator(params),
206
- onError,
207
- }))
208
- })
209
-
210
- mutation.mutate('')
211
-
212
- await resolveMutations()
213
-
214
- expect(onError).toHaveBeenCalledTimes(1)
215
- })
216
-
217
- test('should call onSuccess when passed as an option', async () => {
218
- const onSuccess = vi.fn()
219
- const mutation = TestBed.runInInjectionContext(() => {
220
- return injectMutation(() => ({
221
- mutationFn: (params: string) => successMutator(params),
222
- onSuccess,
223
- }))
224
- })
225
-
226
- mutation.mutate('')
227
-
228
- await resolveMutations()
229
-
230
- expect(onSuccess).toHaveBeenCalledTimes(1)
231
- })
232
-
233
- test('should call onSettled when passed as an option', async () => {
234
- const onSettled = vi.fn()
235
- const mutation = TestBed.runInInjectionContext(() => {
236
- return injectMutation(() => ({
237
- mutationFn: (params: string) => successMutator(params),
238
- onSettled,
239
- }))
240
- })
241
-
242
- mutation.mutate('')
243
-
244
- await resolveMutations()
245
-
246
- expect(onSettled).toHaveBeenCalledTimes(1)
247
- })
248
-
249
- test('should call onError when passed as an argument of mutate function', async () => {
250
- const onError = vi.fn()
251
- const mutation = TestBed.runInInjectionContext(() => {
252
- return injectMutation(() => ({
253
- mutationFn: (params: string) => errorMutator(params),
254
- }))
255
- })
256
-
257
- mutation.mutate('', { onError })
258
-
259
- await resolveMutations()
260
-
261
- expect(onError).toHaveBeenCalledTimes(1)
262
- })
263
-
264
- test('should call onSuccess when passed as an argument of mutate function', async () => {
265
- const onSuccess = vi.fn()
266
- const mutation = TestBed.runInInjectionContext(() => {
267
- return injectMutation(() => ({
268
- mutationFn: (params: string) => successMutator(params),
269
- }))
270
- })
271
-
272
- mutation.mutate('', { onSuccess })
273
-
274
- await resolveMutations()
275
-
276
- expect(onSuccess).toHaveBeenCalledTimes(1)
277
- })
278
-
279
- test('should call onSettled when passed as an argument of mutate function', async () => {
280
- const onSettled = vi.fn()
281
- const mutation = TestBed.runInInjectionContext(() => {
282
- return injectMutation(() => ({
283
- mutationFn: (params: string) => successMutator(params),
284
- }))
285
- })
286
-
287
- mutation.mutate('', { onSettled })
288
-
289
- await resolveMutations()
290
-
291
- expect(onSettled).toHaveBeenCalledTimes(1)
292
- })
293
-
294
- test('should fire both onSettled functions', async () => {
295
- const onSettled = vi.fn()
296
- const onSettledOnFunction = vi.fn()
297
- const mutation = TestBed.runInInjectionContext(() => {
298
- return injectMutation(() => ({
299
- mutationFn: (params: string) => successMutator(params),
300
- onSettled,
301
- }))
302
- })
303
-
304
- mutation.mutate('', { onSettled: onSettledOnFunction })
305
-
306
- await resolveMutations()
307
-
308
- expect(onSettled).toHaveBeenCalledTimes(1)
309
- expect(onSettledOnFunction).toHaveBeenCalledTimes(1)
310
- })
311
- })
312
-
313
- test('should support required signal inputs', async () => {
314
- const mutationCache = queryClient.getMutationCache()
315
-
316
- @Component({
317
- selector: 'app-fake',
318
- template: `
319
- <button (click)="mutate()"></button>
320
- <span>{{ mutation.data() }}</span>
321
- `,
322
- standalone: true,
323
- })
324
- class FakeComponent {
325
- name = input.required<string>()
326
-
327
- mutation = injectMutation(() => ({
328
- mutationKey: ['fake', this.name()],
329
- mutationFn: () => successMutator(this.name()),
330
- }))
331
-
332
- mutate(): void {
333
- this.mutation.mutate()
334
- }
335
- }
336
-
337
- const fixture = TestBed.createComponent(FakeComponent)
338
- const { debugElement } = fixture
339
- setFixtureSignalInputs(fixture, { name: 'value' })
340
-
341
- const button = debugElement.query(By.css('button'))
342
- button.triggerEventHandler('click')
343
-
344
- await resolveMutations()
345
- fixture.detectChanges()
346
-
347
- const text = debugElement.query(By.css('span')).nativeElement.textContent
348
- expect(text).toEqual('value')
349
- const mutation = mutationCache.find({ mutationKey: ['fake', 'value'] })
350
- expect(mutation).toBeDefined()
351
- expect(mutation!.options.mutationKey).toStrictEqual(['fake', 'value'])
352
- })
353
-
354
- test('should update options on required signal input change', async () => {
355
- const mutationCache = queryClient.getMutationCache()
356
-
357
- @Component({
358
- selector: 'app-fake',
359
- template: `
360
- <button (click)="mutate()"></button>
361
- <span>{{ mutation.data() }}</span>
362
- `,
363
- standalone: true,
364
- })
365
- class FakeComponent {
366
- name = input.required<string>()
367
-
368
- mutation = injectMutation(() => ({
369
- mutationKey: ['fake', this.name()],
370
- mutationFn: () => successMutator(this.name()),
371
- }))
372
-
373
- mutate(): void {
374
- this.mutation.mutate()
375
- }
376
- }
377
-
378
- const fixture = TestBed.createComponent(FakeComponent)
379
- const { debugElement } = fixture
380
- setFixtureSignalInputs(fixture, { name: 'value' })
381
-
382
- const button = debugElement.query(By.css('button'))
383
- const span = debugElement.query(By.css('span'))
384
-
385
- button.triggerEventHandler('click')
386
- await resolveMutations()
387
- fixture.detectChanges()
388
-
389
- expect(span.nativeElement.textContent).toEqual('value')
390
-
391
- setFixtureSignalInputs(fixture, { name: 'updatedValue' })
392
-
393
- button.triggerEventHandler('click')
394
- await resolveMutations()
395
- fixture.detectChanges()
396
-
397
- expect(span.nativeElement.textContent).toEqual('updatedValue')
398
-
399
- const mutations = mutationCache.findAll()
400
- expect(mutations.length).toBe(2)
401
- const [mutation1, mutation2] = mutations
402
- expect(mutation1!.options.mutationKey).toEqual(['fake', 'value'])
403
- expect(mutation2!.options.mutationKey).toEqual(['fake', 'updatedValue'])
404
- })
405
-
406
- describe('throwOnError', () => {
407
- test('should evaluate throwOnError when mutation is expected to throw', async () => {
408
- const err = new Error('Expected mock error. All is well!')
409
- const boundaryFn = vi.fn()
410
- const { mutate } = TestBed.runInInjectionContext(() => {
411
- return injectMutation(() => ({
412
- mutationKey: ['fake'],
413
- mutationFn: () => {
414
- return Promise.reject(err)
415
- },
416
- throwOnError: boundaryFn,
417
- }))
418
- })
419
-
420
- mutate()
421
-
422
- await resolveMutations()
423
-
424
- expect(boundaryFn).toHaveBeenCalledTimes(1)
425
- expect(boundaryFn).toHaveBeenCalledWith(err)
426
- })
427
- })
428
-
429
- test('should throw when throwOnError is true', async () => {
430
- const err = new Error('Expected mock error. All is well!')
431
- const { mutateAsync } = TestBed.runInInjectionContext(() => {
432
- return injectMutation(() => ({
433
- mutationKey: ['fake'],
434
- mutationFn: () => {
435
- return Promise.reject(err)
436
- },
437
- throwOnError: true,
438
- }))
439
- })
440
-
441
- await expect(() => mutateAsync()).rejects.toThrowError(err)
442
- })
443
-
444
- test('should throw when throwOnError function returns true', async () => {
445
- const err = new Error('Expected mock error. All is well!')
446
- const { mutateAsync } = TestBed.runInInjectionContext(() => {
447
- return injectMutation(() => ({
448
- mutationKey: ['fake'],
449
- mutationFn: () => {
450
- return Promise.reject(err)
451
- },
452
- throwOnError: () => true,
453
- }))
454
- })
455
-
456
- await expect(() => mutateAsync()).rejects.toThrowError(err)
457
- })
458
- })
@@ -1,59 +0,0 @@
1
- import { describe, expectTypeOf } from 'vitest'
2
- import { injectQuery } from '../inject-query'
3
- import { simpleFetcher } from './test-utils'
4
- import type { Signal } from '@angular/core'
5
-
6
- describe('Discriminated union return type', () => {
7
- test('data should be possibly undefined by default', () => {
8
- const query = injectQuery(() => ({
9
- queryKey: ['key'],
10
- queryFn: simpleFetcher,
11
- }))
12
-
13
- expectTypeOf(query.data).toEqualTypeOf<Signal<string | undefined>>()
14
- })
15
-
16
- test('data should be defined when query is success', () => {
17
- const query = injectQuery(() => ({
18
- queryKey: ['key'],
19
- queryFn: simpleFetcher,
20
- }))
21
-
22
- if (query.isSuccess()) {
23
- expectTypeOf(query.data).toEqualTypeOf<Signal<string>>()
24
- }
25
- })
26
-
27
- test('error should be null when query is success', () => {
28
- const query = injectQuery(() => ({
29
- queryKey: ['key'],
30
- queryFn: simpleFetcher,
31
- }))
32
-
33
- if (query.isSuccess()) {
34
- expectTypeOf(query.error).toEqualTypeOf<Signal<null>>()
35
- }
36
- })
37
-
38
- test('data should be undefined when query is pending', () => {
39
- const query = injectQuery(() => ({
40
- queryKey: ['key'],
41
- queryFn: simpleFetcher,
42
- }))
43
-
44
- if (query.isPending()) {
45
- expectTypeOf(query.data).toEqualTypeOf<Signal<undefined>>()
46
- }
47
- })
48
-
49
- test('error should be defined when query is error', () => {
50
- const query = injectQuery(() => ({
51
- queryKey: ['key'],
52
- queryFn: simpleFetcher,
53
- }))
54
-
55
- if (query.isError()) {
56
- expectTypeOf(query.error).toEqualTypeOf<Signal<Error>>()
57
- }
58
- })
59
- })