1
+ import type { Store } from 'redux'
1
2
import { getBatch } from './batch'
3
+ import type { Node } from './autotracking/tracking'
4
+
5
+ import {
6
+ createCache ,
7
+ TrackingCache ,
8
+ $REVISION ,
9
+ } from './autotracking/autotracking'
10
+ import { updateNode } from './autotracking/proxy'
2
11
3
12
// encapsulates the subscription logic for connecting a component to the redux store, as
4
13
// well as nesting subscriptions of descendant components, so that we can ensure the
@@ -10,6 +19,9 @@ type Listener = {
10
19
callback : VoidFunc
11
20
next : Listener | null
12
21
prev : Listener | null
22
+ trigger : 'always' | 'tracked'
23
+ selectorCache ?: TrackingCache
24
+ subscriberCache ?: TrackingCache
13
25
}
14
26
15
27
function createListenerCollection ( ) {
@@ -24,10 +36,29 @@ function createListenerCollection() {
24
36
} ,
25
37
26
38
notify ( ) {
39
+ //console.log('Notifying subscribers')
27
40
batch ( ( ) => {
28
41
let listener = first
29
42
while ( listener ) {
30
- listener . callback ( )
43
+ //console.log('Listener: ', listener)
44
+ if ( listener . trigger == 'tracked' ) {
45
+ if ( listener . selectorCache ! . needsRecalculation ( ) ) {
46
+ console . log ( 'Calling subscriber due to recalc need' )
47
+ // console.log(
48
+ // 'Calling subscriber due to recalc. Revision before: ',
49
+ // $REVISION
50
+ // )
51
+ listener . callback ( )
52
+ //console.log('Revision after: ', $REVISION)
53
+ } else {
54
+ console . log (
55
+ 'Skipping subscriber, no recalc: ' ,
56
+ listener . selectorCache
57
+ )
58
+ }
59
+ } else {
60
+ listener . callback ( )
61
+ }
31
62
listener = listener . next
32
63
}
33
64
} )
@@ -43,13 +74,29 @@ function createListenerCollection() {
43
74
return listeners
44
75
} ,
45
76
46
- subscribe ( callback : ( ) => void ) {
77
+ subscribe (
78
+ callback : ( ) => void ,
79
+ options : AddNestedSubOptions = { trigger : 'always' }
80
+ ) {
47
81
let isSubscribed = true
48
82
83
+ //console.log('Adding listener: ', options.trigger)
84
+
49
85
let listener : Listener = ( last = {
50
86
callback,
51
87
next : null ,
52
88
prev : last ,
89
+ trigger : options . trigger ,
90
+ selectorCache :
91
+ options . trigger === 'tracked' ? options . cache ! : undefined ,
92
+ // subscriberCache:
93
+ // options.trigger === 'tracked'
94
+ // ? createCache(() => {
95
+ // console.log('Calling subscriberCache')
96
+ // listener.selectorCache!.get()
97
+ // callback()
98
+ // })
99
+ // : undefined,
53
100
} )
54
101
55
102
if ( listener . prev ) {
@@ -79,13 +126,18 @@ function createListenerCollection() {
79
126
80
127
type ListenerCollection = ReturnType < typeof createListenerCollection >
81
128
129
+ interface AddNestedSubOptions {
130
+ trigger : 'always' | 'tracked'
131
+ cache ?: TrackingCache
132
+ }
133
+
82
134
export interface Subscription {
83
- addNestedSub : ( listener : VoidFunc ) => VoidFunc
135
+ addNestedSub : ( listener : VoidFunc , options ?: AddNestedSubOptions ) => VoidFunc
84
136
notifyNestedSubs : VoidFunc
85
137
handleChangeWrapper : VoidFunc
86
138
isSubscribed : ( ) => boolean
87
139
onStateChange ?: VoidFunc | null
88
- trySubscribe : VoidFunc
140
+ trySubscribe : ( options ?: AddNestedSubOptions ) => void
89
141
tryUnsubscribe : VoidFunc
90
142
getListeners : ( ) => ListenerCollection
91
143
}
@@ -95,16 +147,28 @@ const nullListeners = {
95
147
get : ( ) => [ ] ,
96
148
} as unknown as ListenerCollection
97
149
98
- export function createSubscription ( store : any , parentSub ?: Subscription ) {
150
+ export function createSubscription (
151
+ store : Store ,
152
+ parentSub ?: Subscription ,
153
+ trackingNode ?: Node < any >
154
+ ) {
99
155
let unsubscribe : VoidFunc | undefined
100
156
let listeners : ListenerCollection = nullListeners
101
157
102
- function addNestedSub ( listener : ( ) => void ) {
103
- trySubscribe ( )
104
- return listeners . subscribe ( listener )
158
+ function addNestedSub (
159
+ listener : ( ) => void ,
160
+ options : AddNestedSubOptions = { trigger : 'always' }
161
+ ) {
162
+ //console.log('addNestedSub: ', options)
163
+ trySubscribe ( options )
164
+ return listeners . subscribe ( listener , options )
105
165
}
106
166
107
167
function notifyNestedSubs ( ) {
168
+ if ( store && trackingNode ) {
169
+ //console.log('Updating node in notifyNestedSubs')
170
+ updateNode ( trackingNode , store . getState ( ) )
171
+ }
108
172
listeners . notify ( )
109
173
}
110
174
@@ -118,10 +182,11 @@ export function createSubscription(store: any, parentSub?: Subscription) {
118
182
return Boolean ( unsubscribe )
119
183
}
120
184
121
- function trySubscribe ( ) {
185
+ function trySubscribe ( options : AddNestedSubOptions = { trigger : 'always' } ) {
122
186
if ( ! unsubscribe ) {
187
+ //console.log('trySubscribe, parentSub: ', parentSub)
123
188
unsubscribe = parentSub
124
- ? parentSub . addNestedSub ( handleChangeWrapper )
189
+ ? parentSub . addNestedSub ( handleChangeWrapper , options )
125
190
: store . subscribe ( handleChangeWrapper )
126
191
127
192
listeners = createListenerCollection ( )
0 commit comments