11import type { QueryThunk , RejectedAction } from '../buildThunks'
22import type { InternalHandlerBuilder } from './types'
3- import type { SubscriptionState } from '../apiState'
3+ import type {
4+ SubscriptionState ,
5+ QuerySubstateIdentifier ,
6+ Subscribers ,
7+ } from '../apiState'
48import { produceWithPatches } from 'immer'
9+ import { createSlice , PayloadAction , AnyAction } from '@reduxjs/toolkit'
510
611// Copied from https://github.com/feross/queue-microtask
712let promise : Promise < any >
@@ -19,14 +24,69 @@ const queueMicrotaskShim =
1924export const buildBatchedActionsHandler : InternalHandlerBuilder <
2025 [ actionShouldContinue : boolean , subscriptionExists : boolean ]
2126> = ( { api, queryThunk, internalState } ) => {
22- const { actuallyMutateSubscriptions } = api . internalActions
2327 const subscriptionsPrefix = `${ api . reducerPath } /subscriptions`
2428
2529 let previousSubscriptions : SubscriptionState =
2630 null as unknown as SubscriptionState
2731
2832 let dispatchQueued = false
2933
34+ const { updateSubscriptionOptions, unsubscribeQueryResult } =
35+ api . internalActions
36+
37+ // Actually intentionally mutate the subscriptions state used in the middleware
38+ // This is done to speed up perf when loading many components
39+ const actuallyMutateSubscriptions = (
40+ mutableState : SubscriptionState ,
41+ action : AnyAction
42+ ) => {
43+ if ( updateSubscriptionOptions . match ( action ) ) {
44+ const { queryCacheKey, requestId, options } = action . payload
45+
46+ if ( mutableState ?. [ queryCacheKey ] ?. [ requestId ] ) {
47+ mutableState [ queryCacheKey ] ! [ requestId ] = options
48+ }
49+ return true
50+ }
51+ if ( unsubscribeQueryResult . match ( action ) ) {
52+ const { queryCacheKey, requestId } = action . payload
53+ if ( mutableState [ queryCacheKey ] ) {
54+ delete mutableState [ queryCacheKey ] ! [ requestId ]
55+ }
56+ return true
57+ }
58+ if ( api . internalActions . removeQueryResult . match ( action ) ) {
59+ delete mutableState [ action . payload . queryCacheKey ]
60+ return true
61+ }
62+ if ( queryThunk . pending . match ( action ) ) {
63+ const {
64+ meta : { arg, requestId } ,
65+ } = action
66+ if ( arg . subscribe ) {
67+ const substate = ( mutableState [ arg . queryCacheKey ] ??= { } )
68+ substate [ requestId ] =
69+ arg . subscriptionOptions ?? substate [ requestId ] ?? { }
70+
71+ return true
72+ }
73+ }
74+ if ( queryThunk . rejected . match ( action ) ) {
75+ const {
76+ meta : { condition, arg, requestId } ,
77+ } = action
78+ if ( condition && arg . subscribe ) {
79+ const substate = ( mutableState [ arg . queryCacheKey ] ??= { } )
80+ substate [ requestId ] =
81+ arg . subscriptionOptions ?? substate [ requestId ] ?? { }
82+
83+ return true
84+ }
85+ }
86+
87+ return false
88+ }
89+
3090 return ( action , mwApi ) => {
3191 if ( ! previousSubscriptions ) {
3292 // Initialize it the first time this handler runs
0 commit comments