Skip to content

Commit 9fad892

Browse files
feat(subscriptions): add event types and metadata to subscriptions (TanStack#1792)
* feat(subscriptions): add event types and metadata to subscriptions * better types, update tests * remove unnecessary setStateOptions * rename to queryUpdated event, add observers where possible * Cleanup * Update queryObserver.ts
1 parent ca56877 commit 9fad892

File tree

4 files changed

+60
-13
lines changed

4 files changed

+60
-13
lines changed

src/core/query.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ export class Query<
289289
// Stop the query from being garbage collected
290290
this.clearGcTimeout()
291291

292-
this.cache.notify(this)
292+
this.cache.notify({ type: 'observerAdded', query: this, observer })
293293
}
294294
}
295295

@@ -315,7 +315,7 @@ export class Query<
315315
}
316316
}
317317

318-
this.cache.notify(this)
318+
this.cache.notify({ type: 'observerRemoved', query: this, observer })
319319
}
320320
}
321321

@@ -401,7 +401,7 @@ export class Query<
401401
this.optionalRemove()
402402
}
403403
},
404-
onError: error => {
404+
onError: (error: TError | { silent?: boolean }) => {
405405
// Optimistically update state if needed
406406
if (!(isCancelledError(error) && error.silent)) {
407407
this.dispatch({
@@ -451,7 +451,7 @@ export class Query<
451451
observer.onQueryUpdate(action)
452452
})
453453

454-
this.cache.notify(this)
454+
this.cache.notify({ query: this, type: 'queryUpdated', action })
455455
})
456456
}
457457

src/core/queryCache.ts

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import {
44
matchQuery,
55
parseFilterArgs,
66
} from './utils'
7-
import { Query, QueryState } from './query'
7+
import { Action, Query, QueryState } from './query'
88
import type { QueryKey, QueryOptions } from './types'
99
import { notifyManager } from './notifyManager'
1010
import type { QueryClient } from './queryClient'
1111
import { Subscribable } from './subscribable'
12+
import { QueryObserver } from './queryObserver'
1213

1314
// TYPES
1415

@@ -20,7 +21,48 @@ interface QueryHashMap {
2021
[hash: string]: Query<any, any>
2122
}
2223

23-
type QueryCacheListener = (query?: Query) => void
24+
interface NotifyEventQueryAdded {
25+
type: 'queryAdded'
26+
query: Query<any, any>
27+
}
28+
29+
interface NotifyEventQueryRemoved {
30+
type: 'queryRemoved'
31+
query: Query<any, any>
32+
}
33+
34+
interface NotifyEventQueryUpdated {
35+
type: 'queryUpdated'
36+
query: Query<any, any>
37+
action: Action<any, any>
38+
}
39+
40+
interface NotifyEventObserverAdded {
41+
type: 'observerAdded'
42+
query: Query<any, any>
43+
observer: QueryObserver<any, any, any, any>
44+
}
45+
46+
interface NotifyEventObserverRemoved {
47+
type: 'observerRemoved'
48+
query: Query<any, any>
49+
observer: QueryObserver<any, any, any, any>
50+
}
51+
52+
interface NotifyEventObserverResultsUpdated {
53+
type: 'observerResultsUpdated'
54+
query: Query<any, any>
55+
}
56+
57+
type QueryCacheNotifyEvent =
58+
| NotifyEventQueryAdded
59+
| NotifyEventQueryRemoved
60+
| NotifyEventQueryUpdated
61+
| NotifyEventObserverAdded
62+
| NotifyEventObserverRemoved
63+
| NotifyEventObserverResultsUpdated
64+
65+
type QueryCacheListener = (event?: QueryCacheNotifyEvent) => void
2466

2567
// CLASS
2668

@@ -66,7 +108,10 @@ export class QueryCache extends Subscribable<QueryCacheListener> {
66108
if (!this.queriesMap[query.queryHash]) {
67109
this.queriesMap[query.queryHash] = query
68110
this.queries.push(query)
69-
this.notify(query)
111+
this.notify({
112+
type: 'queryAdded',
113+
query,
114+
})
70115
}
71116
}
72117

@@ -82,7 +127,7 @@ export class QueryCache extends Subscribable<QueryCacheListener> {
82127
delete this.queriesMap[query.queryHash]
83128
}
84129

85-
this.notify(query)
130+
this.notify({ type: 'queryRemoved', query })
86131
}
87132
}
88133

@@ -127,10 +172,10 @@ export class QueryCache extends Subscribable<QueryCacheListener> {
127172
: this.queries
128173
}
129174

130-
notify(query?: Query<any, any>) {
175+
notify(event: QueryCacheNotifyEvent) {
131176
notifyManager.batch(() => {
132177
this.listeners.forEach(listener => {
133-
listener(query)
178+
listener(event)
134179
})
135180
})
136181
}

src/core/queryObserver.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,9 @@ export class QueryObserver<
614614

615615
// Then the cache listeners
616616
if (notifyOptions.cache) {
617-
this.client.getQueryCache().notify(this.currentQuery)
617+
this.client
618+
.getQueryCache()
619+
.notify({ query: this.currentQuery, type: 'observerResultsUpdated' })
618620
}
619621
})
620622
}

src/core/tests/queryCache.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ describe('queryCache', () => {
2222
queryClient.setQueryData(key, 'foo')
2323
const query = queryCache.find(key)
2424
await sleep(1)
25-
expect(subscriber).toHaveBeenCalledWith(query)
25+
expect(subscriber).toHaveBeenCalledWith({ query, type: 'queryAdded' })
2626
unsubscribe()
2727
})
2828

@@ -42,7 +42,7 @@ describe('queryCache', () => {
4242
queryClient.prefetchQuery(key, () => 'data')
4343
const query = queryCache.find(key)
4444
await sleep(100)
45-
expect(callback).toHaveBeenCalledWith(query)
45+
expect(callback).toHaveBeenCalledWith({ query, type: 'queryAdded' })
4646
})
4747

4848
test('should notify subscribers when new query with initialData is added', async () => {

0 commit comments

Comments
 (0)