Skip to content

Commit 0da5102

Browse files
authored
Add interaction-tracking/subscriptions (#13426)
* Removed enableInteractionTrackingObserver as a separate flag; only enableInteractionTracking is used now * Added interaction-tracking/subscriptions bundle and split tests * Added multi-subscriber support * Moved subscriptions behind feature flag * Fixed bug with wrap() parameters and added test * Replaced wrap arrow function
1 parent 4b32f52 commit 0da5102

17 files changed

+856
-653
lines changed

packages/interaction-tracking/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"LICENSE",
88
"README.md",
99
"index.js",
10+
"subscriptions.js",
1011
"cjs/",
1112
"umd/"
1213
],

packages/interaction-tracking/src/InteractionTracking.js

Lines changed: 81 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@
77
* @flow
88
*/
99

10-
import {
11-
enableInteractionTracking,
12-
enableInteractionTrackingObserver,
13-
} from 'shared/ReactFeatureFlags';
10+
import {enableInteractionTracking} from 'shared/ReactFeatureFlags';
1411

1512
export type Interaction = {|
1613
__count: number,
@@ -71,18 +68,15 @@ let threadIDCounter: number = 0;
7168
let interactionsRef: InteractionsRef = (null: any);
7269

7370
// Listener(s) to notify when interactions begin and end.
74-
// Note that subscribers are only supported when enableInteractionTrackingObserver is enabled.
7571
let subscriberRef: SubscriberRef = (null: any);
7672

7773
if (enableInteractionTracking) {
7874
interactionsRef = {
7975
current: new Set(),
8076
};
81-
if (enableInteractionTrackingObserver) {
82-
subscriberRef = {
83-
current: null,
84-
};
85-
}
77+
subscriberRef = {
78+
current: null,
79+
};
8680
}
8781

8882
// These values are exported for libraries with advanced use cases (i.e. React).
@@ -127,7 +121,7 @@ export function track(
127121
}
128122

129123
const interaction: Interaction = {
130-
__count: 0,
124+
__count: 1,
131125
id: interactionIDCounter++,
132126
name,
133127
timestamp,
@@ -142,53 +136,42 @@ export function track(
142136
interactions.add(interaction);
143137
interactionsRef.current = interactions;
144138

145-
if (enableInteractionTrackingObserver) {
146-
// Update before calling callback in case it schedules follow-up work.
147-
interaction.__count = 1;
148-
149-
let returnValue;
150-
const subscriber = subscriberRef.current;
139+
const subscriber = subscriberRef.current;
140+
let returnValue;
151141

142+
try {
143+
if (subscriber !== null) {
144+
subscriber.onInteractionTracked(interaction);
145+
}
146+
} finally {
152147
try {
153148
if (subscriber !== null) {
154-
subscriber.onInteractionTracked(interaction);
149+
subscriber.onWorkStarted(interactions, threadID);
155150
}
156151
} finally {
157152
try {
158-
if (subscriber !== null) {
159-
subscriber.onWorkStarted(interactions, threadID);
160-
}
153+
returnValue = callback();
161154
} finally {
155+
interactionsRef.current = prevInteractions;
156+
162157
try {
163-
returnValue = callback();
158+
if (subscriber !== null) {
159+
subscriber.onWorkStopped(interactions, threadID);
160+
}
164161
} finally {
165-
interactionsRef.current = prevInteractions;
162+
interaction.__count--;
166163

167-
try {
168-
if (subscriber !== null) {
169-
subscriber.onWorkStopped(interactions, threadID);
170-
}
171-
} finally {
172-
interaction.__count--;
173-
174-
// If no async work was scheduled for this interaction,
175-
// Notify subscribers that it's completed.
176-
if (subscriber !== null && interaction.__count === 0) {
177-
subscriber.onInteractionScheduledWorkCompleted(interaction);
178-
}
164+
// If no async work was scheduled for this interaction,
165+
// Notify subscribers that it's completed.
166+
if (subscriber !== null && interaction.__count === 0) {
167+
subscriber.onInteractionScheduledWorkCompleted(interaction);
179168
}
180169
}
181170
}
182171
}
183-
184-
return returnValue;
185-
} else {
186-
try {
187-
return callback();
188-
} finally {
189-
interactionsRef.current = prevInteractions;
190-
}
191172
}
173+
174+
return returnValue;
192175
}
193176

194177
export function wrap(
@@ -201,89 +184,77 @@ export function wrap(
201184

202185
const wrappedInteractions = interactionsRef.current;
203186

204-
if (enableInteractionTrackingObserver) {
205-
const subscriber = subscriberRef.current;
206-
if (subscriber !== null) {
207-
subscriber.onWorkScheduled(wrappedInteractions, threadID);
208-
}
209-
210-
// Update the pending async work count for the current interactions.
211-
// Update after calling subscribers in case of error.
212-
wrappedInteractions.forEach(interaction => {
213-
interaction.__count++;
214-
});
187+
let subscriber = subscriberRef.current;
188+
if (subscriber !== null) {
189+
subscriber.onWorkScheduled(wrappedInteractions, threadID);
215190
}
216191

217-
const wrapped = () => {
192+
// Update the pending async work count for the current interactions.
193+
// Update after calling subscribers in case of error.
194+
wrappedInteractions.forEach(interaction => {
195+
interaction.__count++;
196+
});
197+
198+
function wrapped() {
218199
const prevInteractions = interactionsRef.current;
219200
interactionsRef.current = wrappedInteractions;
220201

221-
if (enableInteractionTrackingObserver) {
222-
const subscriber = subscriberRef.current;
202+
subscriber = subscriberRef.current;
223203

224-
try {
225-
let returnValue;
204+
try {
205+
let returnValue;
226206

227-
try {
228-
if (subscriber !== null) {
229-
subscriber.onWorkStarted(wrappedInteractions, threadID);
230-
}
231-
} finally {
232-
try {
233-
returnValue = callback.apply(undefined, arguments);
234-
} finally {
235-
interactionsRef.current = prevInteractions;
236-
237-
if (subscriber !== null) {
238-
subscriber.onWorkStopped(wrappedInteractions, threadID);
239-
}
240-
}
207+
try {
208+
if (subscriber !== null) {
209+
subscriber.onWorkStarted(wrappedInteractions, threadID);
241210
}
242-
243-
return returnValue;
244211
} finally {
245-
// Update pending async counts for all wrapped interactions.
246-
// If this was the last scheduled async work for any of them,
247-
// Mark them as completed.
248-
wrappedInteractions.forEach(interaction => {
249-
interaction.__count--;
212+
try {
213+
returnValue = callback.apply(undefined, arguments);
214+
} finally {
215+
interactionsRef.current = prevInteractions;
250216

251-
if (subscriber !== null && interaction.__count === 0) {
252-
subscriber.onInteractionScheduledWorkCompleted(interaction);
217+
if (subscriber !== null) {
218+
subscriber.onWorkStopped(wrappedInteractions, threadID);
253219
}
254-
});
255-
}
256-
} else {
257-
try {
258-
return callback.apply(undefined, arguments);
259-
} finally {
260-
interactionsRef.current = prevInteractions;
220+
}
261221
}
262-
}
263-
};
264-
265-
if (enableInteractionTrackingObserver) {
266-
wrapped.cancel = () => {
267-
const subscriber = subscriberRef.current;
268222

269-
try {
270-
if (subscriber !== null) {
271-
subscriber.onWorkCanceled(wrappedInteractions, threadID);
223+
return returnValue;
224+
} finally {
225+
// Update pending async counts for all wrapped interactions.
226+
// If this was the last scheduled async work for any of them,
227+
// Mark them as completed.
228+
wrappedInteractions.forEach(interaction => {
229+
interaction.__count--;
230+
231+
if (subscriber !== null && interaction.__count === 0) {
232+
subscriber.onInteractionScheduledWorkCompleted(interaction);
272233
}
273-
} finally {
274-
// Update pending async counts for all wrapped interactions.
275-
// If this was the last scheduled async work for any of them,
276-
// Mark them as completed.
277-
wrappedInteractions.forEach(interaction => {
278-
interaction.__count--;
234+
});
235+
}
236+
}
279237

280-
if (subscriber && interaction.__count === 0) {
281-
subscriber.onInteractionScheduledWorkCompleted(interaction);
282-
}
283-
});
238+
wrapped.cancel = function cancel() {
239+
subscriber = subscriberRef.current;
240+
241+
try {
242+
if (subscriber !== null) {
243+
subscriber.onWorkCanceled(wrappedInteractions, threadID);
284244
}
285-
};
286-
}
245+
} finally {
246+
// Update pending async counts for all wrapped interactions.
247+
// If this was the last scheduled async work for any of them,
248+
// Mark them as completed.
249+
wrappedInteractions.forEach(interaction => {
250+
interaction.__count--;
251+
252+
if (subscriber && interaction.__count === 0) {
253+
subscriber.onInteractionScheduledWorkCompleted(interaction);
254+
}
255+
});
256+
}
257+
};
287258

288259
return wrapped;
289260
}

0 commit comments

Comments
 (0)