Skip to content

Commit 02270be

Browse files
refactor: track-change use ZenObservable over RxJS (#1377)
Co-authored-by: Copilot <[email protected]>
1 parent 82f0e00 commit 02270be

File tree

3 files changed

+32
-25
lines changed

3 files changed

+32
-25
lines changed

packages/plugin-autocapture-browser/src/autocapture-plugin.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ import {
88
DEFAULT_ACTION_CLICK_ALLOWLIST,
99
DEFAULT_DATA_ATTRIBUTE_PREFIX,
1010
IDiagnosticsClient,
11+
getGlobalScope,
12+
multicast,
1113
} from '@amplitude/analytics-core';
1214
import { VERSION } from './version';
1315
import * as constants from './constants';
14-
import { fromEvent, map, type Observable, type Subscription, share } from 'rxjs';
16+
import { fromEvent, map, type Observable, share } from 'rxjs';
1517
import {
1618
createShouldTrackEvent,
1719
type ElementBasedTimestampedEvent,
@@ -31,7 +33,7 @@ import {
3133
groupLabeledEventIdsByEventType,
3234
} from './pageActions/triggers';
3335
import { DataExtractor } from './data-extractor';
34-
import { Observable as ZenObservable } from '@amplitude/analytics-core';
36+
import { Observable as ZenObservable, Unsubscribable } from '@amplitude/analytics-core';
3537

3638
declare global {
3739
interface Window {
@@ -59,7 +61,7 @@ export enum ObservablesEnum {
5961

6062
export interface AllWindowObservables {
6163
[ObservablesEnum.ClickObservable]: Observable<ElementBasedTimestampedEvent<MouseEvent>>;
62-
[ObservablesEnum.ChangeObservable]: Observable<ElementBasedTimestampedEvent<Event>>;
64+
[ObservablesEnum.ChangeObservable]: ZenObservable<ElementBasedTimestampedEvent<Event>>;
6365
// [ObservablesEnum.ErrorObservable]: Observable<TimestampedEvent<ErrorEvent>>;
6466
[ObservablesEnum.NavigateObservable]: Observable<TimestampedEvent<NavigateEvent>> | undefined;
6567
[ObservablesEnum.MutationObservable]: Observable<TimestampedEvent<MutationRecord[]>>;
@@ -112,7 +114,7 @@ export const autocapturePlugin = (
112114
const name = constants.PLUGIN_NAME;
113115
const type = 'enrichment';
114116

115-
const subscriptions: Subscription[] = [];
117+
const subscriptions: Unsubscribable[] = [];
116118

117119
// Create data extractor based on options
118120
const dataExtractor = new DataExtractor(options, context);
@@ -131,16 +133,23 @@ export const autocapturePlugin = (
131133
),
132134
share(),
133135
);
134-
const changeObservable = fromEvent<Event>(document, 'change', { capture: true }).pipe(
135-
map((change) =>
136-
dataExtractor.addAdditionalEventProperties(
137-
change,
138-
'change',
139-
(options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,
140-
dataAttributePrefix,
141-
),
142-
),
143-
share(),
136+
137+
const changeObservable = multicast(
138+
new ZenObservable<ElementBasedTimestampedEvent<Event>>((observer) => {
139+
const handler = (changeEvent: Event) => {
140+
const enrichedChangeEvent = dataExtractor.addAdditionalEventProperties(
141+
changeEvent,
142+
'change',
143+
(options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,
144+
dataAttributePrefix,
145+
) as ElementBasedTimestampedEvent<Event>;
146+
observer.next(enrichedChangeEvent);
147+
};
148+
/* istanbul ignore next */
149+
getGlobalScope()?.document.addEventListener('change', handler, { capture: true });
150+
/* istanbul ignore next */
151+
return () => getGlobalScope()?.document.removeEventListener('change', handler);
152+
}),
144153
);
145154

146155
// Create Observable from unhandled errors
@@ -180,7 +189,7 @@ export const autocapturePlugin = (
180189

181190
return {
182191
[ObservablesEnum.ClickObservable]: clickObservable as Observable<ElementBasedTimestampedEvent<MouseEvent>>,
183-
[ObservablesEnum.ChangeObservable]: changeObservable as Observable<ElementBasedTimestampedEvent<Event>>,
192+
[ObservablesEnum.ChangeObservable]: changeObservable,
184193
// [ObservablesEnum.ErrorObservable]: errorObservable,
185194
[ObservablesEnum.NavigateObservable]: navigateObservable,
186195
[ObservablesEnum.MutationObservable]: mutationObservable,

packages/plugin-autocapture-browser/src/autocapture/track-change.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { AllWindowObservables } from 'src/autocapture-plugin';
2-
import { type evaluateTriggersFn } from 'src/helpers';
3-
import { filter, map } from 'rxjs';
2+
import { ElementBasedTimestampedEvent, type evaluateTriggersFn } from 'src/helpers';
43
import { BrowserClient, ActionType } from '@amplitude/analytics-core';
54
import { filterOutNonTrackableEvents, shouldTrackEvent } from '../helpers';
65
import { AMPLITUDE_ELEMENT_CHANGED_EVENT } from '../constants';
@@ -20,14 +19,13 @@ export function trackChange({
2019
}) {
2120
const { changeObservable } = allObservables;
2221

23-
const filteredChangeObservable = changeObservable.pipe(
24-
filter(filterOutNonTrackableEvents),
25-
filter((changeEvent) => {
22+
const filteredChangeObservable = changeObservable
23+
.filter(filterOutNonTrackableEvents)
24+
.filter((changeEvent: ElementBasedTimestampedEvent<Event>) => {
2625
// Only track change on elements that should be tracked,
2726
return shouldTrackEvent('change', changeEvent.closestTrackedAncestor);
28-
}),
29-
map((changeEvent) => evaluateTriggers(changeEvent)),
30-
);
27+
})
28+
.map((changeEvent) => evaluateTriggers(changeEvent));
3129

3230
return filteredChangeObservable.subscribe((changeEvent) => {
3331
/* istanbul ignore next */

test-server/autocapture/element-interactions.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,9 @@ <h2>Content Changing Button</h2>
268268
import.meta.env.VITE_AMPLITUDE_USER_ID || 'amplitude-typescript test user',
269269
{
270270
identify,
271-
fetchRemoteConfig: true,
271+
fetchRemoteConfig: false,
272272
autocapture: {
273-
elementInteractions: false,
273+
elementInteractions: true,
274274
frustrationInteractions,
275275
sessions: true,
276276
},

0 commit comments

Comments
 (0)