@@ -11,6 +11,16 @@ import type {
11
11
12
12
export type ReferenceCacheCollection = never
13
13
14
+ function isObjectEmpty ( obj : Record < any , any > ) {
15
+ // Apparently a for..in loop is faster than `Object.keys()` here:
16
+ // https://stackoverflow.com/a/59787784/62937
17
+ for ( let k in obj ) {
18
+ // If there is at least one key, it's not empty
19
+ return false
20
+ }
21
+ return true
22
+ }
23
+
14
24
declare module '../../endpointDefinitions' {
15
25
interface QueryExtraOptions <
16
26
TagTypes extends string ,
@@ -38,6 +48,15 @@ export const THIRTY_TWO_BIT_MAX_TIMER_SECONDS = 2_147_483_647 / 1_000 - 1
38
48
export const build : SubMiddlewareBuilder = ( { reducerPath, api, context } ) => {
39
49
const { removeQueryResult, unsubscribeQueryResult } = api . internalActions
40
50
51
+ function anySubscriptionsRemainingForKey (
52
+ queryCacheKey : string ,
53
+ api : SubMiddlewareApi
54
+ ) {
55
+ const subscriptions =
56
+ api . getState ( ) [ reducerPath ] . subscriptions [ queryCacheKey ]
57
+ return ! ! subscriptions && ! isObjectEmpty ( subscriptions )
58
+ }
59
+
41
60
return ( mwApi ) => {
42
61
const currentRemovalTimeouts : QueryStateMeta < TimeoutId > = { }
43
62
@@ -103,18 +122,18 @@ export const build: SubMiddlewareBuilder = ({ reducerPath, api, context }) => {
103
122
Math . min ( keepUnusedDataFor , THIRTY_TWO_BIT_MAX_TIMER_SECONDS )
104
123
)
105
124
106
- const currentTimeout = currentRemovalTimeouts [ queryCacheKey ]
107
- if ( currentTimeout ) {
108
- clearTimeout ( currentTimeout )
109
- }
110
- currentRemovalTimeouts [ queryCacheKey ] = setTimeout ( ( ) => {
111
- const subscriptions =
112
- api . getState ( ) [ reducerPath ] . subscriptions [ queryCacheKey ]
113
- if ( ! subscriptions || Object . keys ( subscriptions ) . length === 0 ) {
114
- api . dispatch ( removeQueryResult ( { queryCacheKey } ) )
125
+ if ( ! anySubscriptionsRemainingForKey ( queryCacheKey , api ) ) {
126
+ const currentTimeout = currentRemovalTimeouts [ queryCacheKey ]
127
+ if ( currentTimeout ) {
128
+ clearTimeout ( currentTimeout )
115
129
}
116
- delete currentRemovalTimeouts ! [ queryCacheKey ]
117
- } , finalKeepUnusedDataFor * 1000 )
130
+ currentRemovalTimeouts [ queryCacheKey ] = setTimeout ( ( ) => {
131
+ if ( ! anySubscriptionsRemainingForKey ( queryCacheKey , api ) ) {
132
+ api . dispatch ( removeQueryResult ( { queryCacheKey } ) )
133
+ }
134
+ delete currentRemovalTimeouts ! [ queryCacheKey ]
135
+ } , finalKeepUnusedDataFor * 1000 )
136
+ }
118
137
}
119
138
}
120
139
}
0 commit comments