@amplitude/plugin-autocapture-browser 1.19.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/autocapture/track-thrashed-cursor.d.ts +23 -0
- package/lib/cjs/autocapture/track-thrashed-cursor.d.ts.map +1 -0
- package/lib/cjs/autocapture/track-thrashed-cursor.js +180 -0
- package/lib/cjs/autocapture/track-thrashed-cursor.js.map +1 -0
- package/lib/cjs/autocapture-plugin.d.ts +2 -1
- package/lib/cjs/autocapture-plugin.d.ts.map +1 -1
- package/lib/cjs/autocapture-plugin.js +1 -0
- package/lib/cjs/autocapture-plugin.js.map +1 -1
- package/lib/cjs/constants.d.ts +1 -0
- package/lib/cjs/constants.d.ts.map +1 -1
- package/lib/cjs/constants.js +2 -1
- package/lib/cjs/constants.js.map +1 -1
- package/lib/cjs/frustration-plugin.d.ts +1 -0
- package/lib/cjs/frustration-plugin.d.ts.map +1 -1
- package/lib/cjs/frustration-plugin.js +33 -1
- package/lib/cjs/frustration-plugin.js.map +1 -1
- package/lib/cjs/helpers.d.ts +1 -0
- package/lib/cjs/helpers.d.ts.map +1 -1
- package/lib/cjs/helpers.js +18 -10
- package/lib/cjs/helpers.js.map +1 -1
- package/lib/cjs/observables.d.ts +1 -0
- package/lib/cjs/observables.d.ts.map +1 -1
- package/lib/cjs/observables.js +19 -3
- package/lib/cjs/observables.js.map +1 -1
- package/lib/cjs/version.d.ts +1 -1
- package/lib/cjs/version.js +1 -1
- package/lib/cjs/version.js.map +1 -1
- package/lib/esm/autocapture/track-thrashed-cursor.d.ts +23 -0
- package/lib/esm/autocapture/track-thrashed-cursor.d.ts.map +1 -0
- package/lib/esm/autocapture/track-thrashed-cursor.js +174 -0
- package/lib/esm/autocapture/track-thrashed-cursor.js.map +1 -0
- package/lib/esm/autocapture-plugin.d.ts +2 -1
- package/lib/esm/autocapture-plugin.d.ts.map +1 -1
- package/lib/esm/autocapture-plugin.js +1 -0
- package/lib/esm/autocapture-plugin.js.map +1 -1
- package/lib/esm/constants.d.ts +1 -0
- package/lib/esm/constants.d.ts.map +1 -1
- package/lib/esm/constants.js +1 -0
- package/lib/esm/constants.js.map +1 -1
- package/lib/esm/frustration-plugin.d.ts +1 -0
- package/lib/esm/frustration-plugin.d.ts.map +1 -1
- package/lib/esm/frustration-plugin.js +34 -2
- package/lib/esm/frustration-plugin.js.map +1 -1
- package/lib/esm/helpers.d.ts +1 -0
- package/lib/esm/helpers.d.ts.map +1 -1
- package/lib/esm/helpers.js +16 -9
- package/lib/esm/helpers.js.map +1 -1
- package/lib/esm/observables.d.ts +1 -0
- package/lib/esm/observables.d.ts.map +1 -1
- package/lib/esm/observables.js +17 -2
- package/lib/esm/observables.js.map +1 -1
- package/lib/esm/version.d.ts +1 -1
- package/lib/esm/version.js +1 -1
- package/lib/esm/version.js.map +1 -1
- package/lib/scripts/amplitude-min.js +1 -1
- package/lib/scripts/amplitude-min.js.gz +0 -0
- package/lib/scripts/amplitude-min.js.map +1 -1
- package/lib/scripts/amplitude-min.umd.js +1 -1
- package/lib/scripts/amplitude-min.umd.js.gz +0 -0
- package/lib/scripts/autocapture/track-thrashed-cursor.d.ts +23 -0
- package/lib/scripts/autocapture/track-thrashed-cursor.d.ts.map +1 -0
- package/lib/scripts/autocapture-plugin.d.ts +2 -1
- package/lib/scripts/autocapture-plugin.d.ts.map +1 -1
- package/lib/scripts/constants.d.ts +1 -0
- package/lib/scripts/constants.d.ts.map +1 -1
- package/lib/scripts/frustration-plugin.d.ts +1 -0
- package/lib/scripts/frustration-plugin.d.ts.map +1 -1
- package/lib/scripts/helpers.d.ts +1 -0
- package/lib/scripts/helpers.d.ts.map +1 -1
- package/lib/scripts/observables.d.ts +1 -0
- package/lib/scripts/observables.d.ts.map +1 -1
- package/lib/scripts/version.d.ts +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BrowserClient, ElementInteractionsOptions, Observable } from '@amplitude/analytics-core';
|
|
2
|
+
import { AllWindowObservables } from '../frustration-plugin';
|
|
3
|
+
declare enum Axis {
|
|
4
|
+
X = "x",
|
|
5
|
+
Y = "y"
|
|
6
|
+
}
|
|
7
|
+
export declare const createMouseDirectionChangeObservable: ({ allWindowObservables, }: {
|
|
8
|
+
allWindowObservables: AllWindowObservables;
|
|
9
|
+
}) => Observable<Axis>;
|
|
10
|
+
export declare const createThrashedCursorObservable: ({ mouseDirectionChangeObservable, directionChanges, thresholdMs, }: {
|
|
11
|
+
mouseDirectionChangeObservable: Observable<Axis>;
|
|
12
|
+
directionChanges?: number | undefined;
|
|
13
|
+
thresholdMs?: number | undefined;
|
|
14
|
+
}) => Observable<number>;
|
|
15
|
+
export declare const trackThrashedCursor: ({ amplitude, options, allObservables, directionChanges, thresholdMs, }: {
|
|
16
|
+
amplitude: BrowserClient;
|
|
17
|
+
options: ElementInteractionsOptions;
|
|
18
|
+
allObservables: AllWindowObservables;
|
|
19
|
+
directionChanges?: number | undefined;
|
|
20
|
+
thresholdMs?: number | undefined;
|
|
21
|
+
}) => ZenObservable.Subscription;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=track-thrashed-cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-thrashed-cursor.d.ts","sourceRoot":"","sources":["../../../src/autocapture/track-thrashed-cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAClG,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAc7D,aAAK,IAAI;IACP,CAAC,MAAM;IACP,CAAC,MAAM;CACR;AAED,eAAO,MAAM,oCAAoC;0BAGzB,oBAAoB;MACxC,WAAW,IAAI,CAsClB,CAAC;AA8EF,eAAO,MAAM,8BAA8B;oCAKT,WAAW,IAAI,CAAC;;;MAG9C,WAAW,MAAM,CAkDpB,CAAC;AAEF,eAAO,MAAM,mBAAmB;eAOnB,aAAa;aACf,0BAA0B;oBACnB,oBAAoB;;;gCAgBrC,CAAC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.trackThrashedCursor = exports.createThrashedCursorObservable = exports.createMouseDirectionChangeObservable = void 0;
|
|
4
|
+
var analytics_core_1 = require("@amplitude/analytics-core");
|
|
5
|
+
var constants_1 = require("../constants");
|
|
6
|
+
var helpers_1 = require("../helpers");
|
|
7
|
+
var Direction;
|
|
8
|
+
(function (Direction) {
|
|
9
|
+
Direction["INCREASING"] = "increasing";
|
|
10
|
+
Direction["DECREASING"] = "decreasing";
|
|
11
|
+
})(Direction || (Direction = {}));
|
|
12
|
+
var Axis;
|
|
13
|
+
(function (Axis) {
|
|
14
|
+
Axis["X"] = "x";
|
|
15
|
+
Axis["Y"] = "y";
|
|
16
|
+
})(Axis || (Axis = {}));
|
|
17
|
+
var createMouseDirectionChangeObservable = function (_a) {
|
|
18
|
+
var allWindowObservables = _a.allWindowObservables;
|
|
19
|
+
var mouseMoveObservable = allWindowObservables.mouseMoveObservable;
|
|
20
|
+
return new analytics_core_1.Observable(function (observer) {
|
|
21
|
+
var lastPosition = null;
|
|
22
|
+
var xDirection = null;
|
|
23
|
+
var yDirection = null;
|
|
24
|
+
return mouseMoveObservable.subscribe(function (event) {
|
|
25
|
+
var currentPosition = { x: event.clientX, y: event.clientY };
|
|
26
|
+
if (lastPosition === null) {
|
|
27
|
+
lastPosition = currentPosition;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (currentPosition.x > lastPosition.x) {
|
|
31
|
+
if (xDirection === Direction.DECREASING) {
|
|
32
|
+
observer.next(Axis.X);
|
|
33
|
+
}
|
|
34
|
+
xDirection = Direction.INCREASING;
|
|
35
|
+
}
|
|
36
|
+
else if (currentPosition.x < lastPosition.x) {
|
|
37
|
+
if (xDirection === Direction.INCREASING) {
|
|
38
|
+
observer.next(Axis.X);
|
|
39
|
+
}
|
|
40
|
+
xDirection = Direction.DECREASING;
|
|
41
|
+
}
|
|
42
|
+
if (currentPosition.y > lastPosition.y) {
|
|
43
|
+
if (yDirection === Direction.DECREASING) {
|
|
44
|
+
observer.next(Axis.Y);
|
|
45
|
+
}
|
|
46
|
+
yDirection = Direction.INCREASING;
|
|
47
|
+
}
|
|
48
|
+
else if (currentPosition.y < lastPosition.y) {
|
|
49
|
+
if (yDirection === Direction.INCREASING) {
|
|
50
|
+
observer.next(Axis.Y);
|
|
51
|
+
}
|
|
52
|
+
yDirection = Direction.DECREASING;
|
|
53
|
+
}
|
|
54
|
+
lastPosition = currentPosition;
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
exports.createMouseDirectionChangeObservable = createMouseDirectionChangeObservable;
|
|
59
|
+
function addDirectionChange(directionChangeSeries) {
|
|
60
|
+
var now = +Date.now();
|
|
61
|
+
directionChangeSeries.startTime = directionChangeSeries.startTime || now;
|
|
62
|
+
// add this direction change to the series (fixed length array to avoid memory leaks)
|
|
63
|
+
var changes = directionChangeSeries.changes, changesThreshold = directionChangeSeries.changesThreshold;
|
|
64
|
+
changes.push(now);
|
|
65
|
+
if (changes.length > changesThreshold)
|
|
66
|
+
changes.shift();
|
|
67
|
+
}
|
|
68
|
+
// checks if there are enough direction changes within window + threshold
|
|
69
|
+
// for it to be considered a thrashed cursor
|
|
70
|
+
function isThrashedCursor(directionChanges) {
|
|
71
|
+
var changes = directionChanges.changes, changesThreshold = directionChanges.changesThreshold, thresholdMs = directionChanges.thresholdMs;
|
|
72
|
+
if (changes.length < changesThreshold)
|
|
73
|
+
return false;
|
|
74
|
+
var delta = changes[changes.length - 1] - changes[0];
|
|
75
|
+
return delta < thresholdMs;
|
|
76
|
+
}
|
|
77
|
+
function resetDirectionChangeSeries(directionChangeSeries) {
|
|
78
|
+
directionChangeSeries.changes = [];
|
|
79
|
+
directionChangeSeries.startTime = undefined;
|
|
80
|
+
}
|
|
81
|
+
// if the time between first and last change is greater than the threshold,
|
|
82
|
+
// shift the window to the right until it is below the threshold
|
|
83
|
+
function adjustWindow(directionChanges) {
|
|
84
|
+
var changes = directionChanges.changes, thresholdMs = directionChanges.thresholdMs;
|
|
85
|
+
// find the first change that is within the threshold
|
|
86
|
+
var leftPtr = 0;
|
|
87
|
+
var lastChange = changes[changes.length - 1];
|
|
88
|
+
for (; leftPtr < changes.length; leftPtr++) {
|
|
89
|
+
var delta = lastChange - changes[leftPtr];
|
|
90
|
+
if (delta < thresholdMs) {
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (leftPtr === 0)
|
|
95
|
+
return;
|
|
96
|
+
directionChanges.startTime = changes[leftPtr];
|
|
97
|
+
directionChanges.changes.splice(0, leftPtr);
|
|
98
|
+
}
|
|
99
|
+
function getPendingThrashedCursor(directionChangesX, directionChangesY) {
|
|
100
|
+
var startTime = undefined;
|
|
101
|
+
if (isThrashedCursor(directionChangesX)) {
|
|
102
|
+
startTime = directionChangesX.startTime;
|
|
103
|
+
}
|
|
104
|
+
if (isThrashedCursor(directionChangesY)) {
|
|
105
|
+
var startTimeY = directionChangesY.startTime;
|
|
106
|
+
if (startTimeY && (!startTime || startTimeY < startTime)) {
|
|
107
|
+
startTime = startTimeY;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return startTime;
|
|
111
|
+
}
|
|
112
|
+
var DEFAULT_THRESHOLD = 10;
|
|
113
|
+
var DEFAULT_WINDOW_MS = 2000;
|
|
114
|
+
var createThrashedCursorObservable = function (_a) {
|
|
115
|
+
var mouseDirectionChangeObservable = _a.mouseDirectionChangeObservable, _b = _a.directionChanges, directionChanges = _b === void 0 ? DEFAULT_THRESHOLD : _b, _c = _a.thresholdMs, thresholdMs = _c === void 0 ? DEFAULT_WINDOW_MS : _c;
|
|
116
|
+
return new analytics_core_1.Observable(function (observer) {
|
|
117
|
+
var xDirectionChanges = { changes: [], changesThreshold: directionChanges, thresholdMs: thresholdMs };
|
|
118
|
+
var yDirectionChanges = { changes: [], changesThreshold: directionChanges, thresholdMs: thresholdMs };
|
|
119
|
+
var pendingThrashedCursor = undefined;
|
|
120
|
+
var timer = null;
|
|
121
|
+
function emitPendingThrashedCursor() {
|
|
122
|
+
if (pendingThrashedCursor !== undefined) {
|
|
123
|
+
observer.next(pendingThrashedCursor);
|
|
124
|
+
pendingThrashedCursor = undefined;
|
|
125
|
+
// reset window
|
|
126
|
+
if (timer !== null)
|
|
127
|
+
clearTimeout(timer);
|
|
128
|
+
resetDirectionChangeSeries(xDirectionChanges);
|
|
129
|
+
resetDirectionChangeSeries(yDirectionChanges);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return mouseDirectionChangeObservable.subscribe(function (axis) {
|
|
133
|
+
if (timer !== null)
|
|
134
|
+
clearTimeout(timer);
|
|
135
|
+
addDirectionChange(axis === Axis.X ? xDirectionChanges : yDirectionChanges);
|
|
136
|
+
var nextPendingThrashedCursor = getPendingThrashedCursor(xDirectionChanges, yDirectionChanges);
|
|
137
|
+
if (nextPendingThrashedCursor) {
|
|
138
|
+
// if we're in a thrashed cursor window, debounce it for "thresholdMs" duration
|
|
139
|
+
// this is so that we do not restart the window if more direction changes are
|
|
140
|
+
// detected in this series
|
|
141
|
+
pendingThrashedCursor = pendingThrashedCursor || nextPendingThrashedCursor;
|
|
142
|
+
timer = setTimeout(function () {
|
|
143
|
+
emitPendingThrashedCursor();
|
|
144
|
+
timer = null;
|
|
145
|
+
}, thresholdMs);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
emitPendingThrashedCursor();
|
|
149
|
+
}
|
|
150
|
+
adjustWindow(xDirectionChanges);
|
|
151
|
+
adjustWindow(yDirectionChanges);
|
|
152
|
+
/* istanbul ignore next */
|
|
153
|
+
return function () {
|
|
154
|
+
/* istanbul ignore if */
|
|
155
|
+
if (timer !== null) {
|
|
156
|
+
clearTimeout(timer);
|
|
157
|
+
timer = null;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
exports.createThrashedCursorObservable = createThrashedCursorObservable;
|
|
164
|
+
var trackThrashedCursor = function (_a) {
|
|
165
|
+
var amplitude = _a.amplitude, options = _a.options, allObservables = _a.allObservables, _b = _a.directionChanges, directionChanges = _b === void 0 ? DEFAULT_THRESHOLD : _b, _c = _a.thresholdMs, thresholdMs = _c === void 0 ? DEFAULT_WINDOW_MS : _c;
|
|
166
|
+
var mouseDirectionChangeObservable = (0, exports.createMouseDirectionChangeObservable)({ allWindowObservables: allObservables });
|
|
167
|
+
var thrashedCursorObservable = (0, exports.createThrashedCursorObservable)({
|
|
168
|
+
mouseDirectionChangeObservable: mouseDirectionChangeObservable,
|
|
169
|
+
directionChanges: directionChanges,
|
|
170
|
+
thresholdMs: thresholdMs,
|
|
171
|
+
});
|
|
172
|
+
return thrashedCursorObservable.subscribe(function (time) {
|
|
173
|
+
if (!(0, helpers_1.isUrlAllowed)(options)) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
amplitude.track(constants_1.AMPLITUDE_THRASHED_CURSOR_EVENT, undefined, { time: time });
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
exports.trackThrashedCursor = trackThrashedCursor;
|
|
180
|
+
//# sourceMappingURL=track-thrashed-cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-thrashed-cursor.js","sourceRoot":"","sources":["../../../src/autocapture/track-thrashed-cursor.ts"],"names":[],"mappings":"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","sourcesContent":["import { BrowserClient, ElementInteractionsOptions, Observable } from '@amplitude/analytics-core';\nimport { AllWindowObservables } from '../frustration-plugin';\nimport { AMPLITUDE_THRASHED_CURSOR_EVENT } from '../constants';\nimport { isUrlAllowed } from '../helpers';\n\ntype Position = {\n x: number;\n y: number;\n};\n\nenum Direction {\n INCREASING = 'increasing',\n DECREASING = 'decreasing',\n}\n\nenum Axis {\n X = 'x',\n Y = 'y',\n}\n\nexport const createMouseDirectionChangeObservable = ({\n allWindowObservables,\n}: {\n allWindowObservables: AllWindowObservables;\n}): Observable<Axis> => {\n const { mouseMoveObservable } = allWindowObservables;\n return new Observable<Axis>((observer) => {\n let lastPosition: Position | null = null;\n let xDirection: Direction | null = null;\n let yDirection: Direction | null = null;\n return mouseMoveObservable.subscribe((event) => {\n const currentPosition = { x: event.clientX, y: event.clientY };\n if (lastPosition === null) {\n lastPosition = currentPosition;\n return;\n }\n if (currentPosition.x > lastPosition.x) {\n if (xDirection === Direction.DECREASING) {\n observer.next(Axis.X);\n }\n xDirection = Direction.INCREASING;\n } else if (currentPosition.x < lastPosition.x) {\n if (xDirection === Direction.INCREASING) {\n observer.next(Axis.X);\n }\n xDirection = Direction.DECREASING;\n }\n\n if (currentPosition.y > lastPosition.y) {\n if (yDirection === Direction.DECREASING) {\n observer.next(Axis.Y);\n }\n yDirection = Direction.INCREASING;\n } else if (currentPosition.y < lastPosition.y) {\n if (yDirection === Direction.INCREASING) {\n observer.next(Axis.Y);\n }\n yDirection = Direction.DECREASING;\n }\n lastPosition = currentPosition;\n });\n });\n};\n\ntype DirectionChangeSeries = {\n // number of direction changes to be considered a thrashed cursor\n changesThreshold: number;\n // timestamps of direction changes (limited to \"changesThreshold\" to avoid memory leaks)\n changes: number[];\n // window duration in milliseconds\n thresholdMs: number;\n // when the series of direction changes started\n startTime?: number;\n};\n\nfunction addDirectionChange(directionChangeSeries: DirectionChangeSeries) {\n const now = +Date.now();\n\n directionChangeSeries.startTime = directionChangeSeries.startTime || now;\n\n // add this direction change to the series (fixed length array to avoid memory leaks)\n const { changes, changesThreshold } = directionChangeSeries;\n changes.push(now);\n if (changes.length > changesThreshold) changes.shift();\n}\n\n// checks if there are enough direction changes within window + threshold\n// for it to be considered a thrashed cursor\nfunction isThrashedCursor(directionChanges: DirectionChangeSeries): boolean {\n const { changes, changesThreshold, thresholdMs } = directionChanges;\n if (changes.length < changesThreshold) return false;\n const delta = changes[changes.length - 1] - changes[0];\n return delta < thresholdMs;\n}\n\nfunction resetDirectionChangeSeries(directionChangeSeries: DirectionChangeSeries) {\n directionChangeSeries.changes = [];\n directionChangeSeries.startTime = undefined;\n}\n\n// if the time between first and last change is greater than the threshold,\n// shift the window to the right until it is below the threshold\nfunction adjustWindow(directionChanges: DirectionChangeSeries) {\n const { changes, thresholdMs } = directionChanges;\n\n // find the first change that is within the threshold\n let leftPtr = 0;\n const lastChange = changes[changes.length - 1];\n for (; leftPtr < changes.length; leftPtr++) {\n const delta = lastChange - changes[leftPtr];\n if (delta < thresholdMs) {\n break;\n }\n }\n if (leftPtr === 0) return;\n\n directionChanges.startTime = changes[leftPtr];\n directionChanges.changes.splice(0, leftPtr);\n}\n\nfunction getPendingThrashedCursor(\n directionChangesX: DirectionChangeSeries,\n directionChangesY: DirectionChangeSeries,\n): number | undefined {\n let startTime = undefined;\n if (isThrashedCursor(directionChangesX)) {\n startTime = directionChangesX.startTime;\n }\n if (isThrashedCursor(directionChangesY)) {\n const startTimeY = directionChangesY.startTime;\n if (startTimeY && (!startTime || startTimeY < startTime)) {\n startTime = startTimeY;\n }\n }\n return startTime;\n}\n\nconst DEFAULT_THRESHOLD = 10;\nconst DEFAULT_WINDOW_MS = 2_000;\n\nexport const createThrashedCursorObservable = ({\n mouseDirectionChangeObservable,\n directionChanges = DEFAULT_THRESHOLD,\n thresholdMs = DEFAULT_WINDOW_MS,\n}: {\n mouseDirectionChangeObservable: Observable<Axis>;\n directionChanges?: number;\n thresholdMs?: number;\n}): Observable<number> => {\n return new Observable<number>((observer) => {\n const xDirectionChanges: DirectionChangeSeries = { changes: [], changesThreshold: directionChanges, thresholdMs };\n const yDirectionChanges: DirectionChangeSeries = { changes: [], changesThreshold: directionChanges, thresholdMs };\n let pendingThrashedCursor: number | undefined = undefined;\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n function emitPendingThrashedCursor() {\n if (pendingThrashedCursor !== undefined) {\n observer.next(pendingThrashedCursor);\n pendingThrashedCursor = undefined;\n\n // reset window\n if (timer !== null) clearTimeout(timer);\n resetDirectionChangeSeries(xDirectionChanges);\n resetDirectionChangeSeries(yDirectionChanges);\n }\n }\n\n return mouseDirectionChangeObservable.subscribe((axis) => {\n if (timer !== null) clearTimeout(timer);\n addDirectionChange(axis === Axis.X ? xDirectionChanges : yDirectionChanges);\n\n const nextPendingThrashedCursor = getPendingThrashedCursor(xDirectionChanges, yDirectionChanges);\n if (nextPendingThrashedCursor) {\n // if we're in a thrashed cursor window, debounce it for \"thresholdMs\" duration\n // this is so that we do not restart the window if more direction changes are\n // detected in this series\n pendingThrashedCursor = pendingThrashedCursor || nextPendingThrashedCursor;\n timer = setTimeout(() => {\n emitPendingThrashedCursor();\n timer = null;\n }, thresholdMs);\n } else {\n emitPendingThrashedCursor();\n }\n\n adjustWindow(xDirectionChanges);\n adjustWindow(yDirectionChanges);\n\n /* istanbul ignore next */\n return () => {\n /* istanbul ignore if */\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n };\n });\n });\n};\n\nexport const trackThrashedCursor = ({\n amplitude,\n options,\n allObservables,\n directionChanges = DEFAULT_THRESHOLD,\n thresholdMs = DEFAULT_WINDOW_MS,\n}: {\n amplitude: BrowserClient;\n options: ElementInteractionsOptions;\n allObservables: AllWindowObservables;\n directionChanges?: number;\n thresholdMs?: number;\n}) => {\n const mouseDirectionChangeObservable = createMouseDirectionChangeObservable({ allWindowObservables: allObservables });\n const thrashedCursorObservable = createThrashedCursorObservable({\n mouseDirectionChangeObservable,\n directionChanges,\n thresholdMs,\n });\n return thrashedCursorObservable.subscribe((time) => {\n if (!isUrlAllowed(options)) {\n return;\n }\n amplitude.track(AMPLITUDE_THRASHED_CURSOR_EVENT, undefined, { time });\n });\n};\n"]}
|
|
@@ -18,7 +18,8 @@ export declare enum ObservablesEnum {
|
|
|
18
18
|
NavigateObservable = "navigateObservable",
|
|
19
19
|
MutationObservable = "mutationObservable",
|
|
20
20
|
BrowserErrorObservable = "browserErrorObservable",
|
|
21
|
-
SelectionObservable = "selectionObservable"
|
|
21
|
+
SelectionObservable = "selectionObservable",
|
|
22
|
+
MouseMoveObservable = "mouseMoveObservable"
|
|
22
23
|
}
|
|
23
24
|
export interface AllWindowObservables {
|
|
24
25
|
[ObservablesEnum.ChangeObservable]: Observable<ElementBasedTimestampedEvent<Event>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autocapture-plugin.d.ts","sourceRoot":"","sources":["../../src/autocapture-plugin.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,EAI/B,kBAAkB,EAGnB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAEL,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAanB,OAAO,EAAE,UAAU,EAAkB,MAAM,2BAA2B,CAAC;AAEvE,KAAK,cAAc,GAAG;IACpB,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,kCAAkC,KAAK,IAAI,CAAC;IACvF,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,kCAAkC,KAAK,IAAI,CAAC;CAC3F,CAAC;AAEF,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,EAAE,cAAc,CAAC;KAC5B;CACF;AAED,KAAK,uBAAuB,GAAG,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAE9E,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CACnD,IAAI,CAAC,0BAA0B,EAAE,cAAc,GAAG,sBAAsB,GAAG,sBAAsB,CAAC,CACnG,GACC,0BAA0B,CAAC;AAE7B,oBAAY,eAAe;IACzB,eAAe,oBAAoB;IACnC,gBAAgB,qBAAqB;IAErC,kBAAkB,uBAAuB;IACzC,kBAAkB,uBAAuB;IACzC,sBAAsB,2BAA2B;IACjD,mBAAmB,wBAAwB;CAC5C;AAED,MAAM,WAAW,oBAAoB;IACnC,CAAC,eAAe,CAAC,gBAAgB,CAAC,EAAE,UAAU,CAAC,4BAA4B,CAAC,KAAK,CAAC,CAAC,CAAC;IAEpF,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAAC;IACxF,CAAC,eAAe,CAAC,kBAAkB,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;IACrF,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC;IACnF,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;CAC1D;AAED,eAAO,MAAM,iBAAiB,aACnB,0BAA0B,YACzB;IAAE,iBAAiB,EAAE,kBAAkB,CAAA;CAAE,KAClD,uBAiQF,CAAC"}
|
|
1
|
+
{"version":3,"file":"autocapture-plugin.d.ts","sourceRoot":"","sources":["../../src/autocapture-plugin.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,EAI/B,kBAAkB,EAGnB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAEL,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAanB,OAAO,EAAE,UAAU,EAAkB,MAAM,2BAA2B,CAAC;AAEvE,KAAK,cAAc,GAAG;IACpB,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,kCAAkC,KAAK,IAAI,CAAC;IACvF,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,kCAAkC,KAAK,IAAI,CAAC;CAC3F,CAAC;AAEF,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,EAAE,cAAc,CAAC;KAC5B;CACF;AAED,KAAK,uBAAuB,GAAG,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAE9E,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CACnD,IAAI,CAAC,0BAA0B,EAAE,cAAc,GAAG,sBAAsB,GAAG,sBAAsB,CAAC,CACnG,GACC,0BAA0B,CAAC;AAE7B,oBAAY,eAAe;IACzB,eAAe,oBAAoB;IACnC,gBAAgB,qBAAqB;IAErC,kBAAkB,uBAAuB;IACzC,kBAAkB,uBAAuB;IACzC,sBAAsB,2BAA2B;IACjD,mBAAmB,wBAAwB;IAC3C,mBAAmB,wBAAwB;CAC5C;AAED,MAAM,WAAW,oBAAoB;IACnC,CAAC,eAAe,CAAC,gBAAgB,CAAC,EAAE,UAAU,CAAC,4BAA4B,CAAC,KAAK,CAAC,CAAC,CAAC;IAEpF,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAAC;IACxF,CAAC,eAAe,CAAC,kBAAkB,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;IACrF,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC;IACnF,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;CAC1D;AAED,eAAO,MAAM,iBAAiB,aACnB,0BAA0B,YACzB;IAAE,iBAAiB,EAAE,kBAAkB,CAAA;CAAE,KAClD,uBAiQF,CAAC"}
|
|
@@ -24,6 +24,7 @@ var ObservablesEnum;
|
|
|
24
24
|
ObservablesEnum["MutationObservable"] = "mutationObservable";
|
|
25
25
|
ObservablesEnum["BrowserErrorObservable"] = "browserErrorObservable";
|
|
26
26
|
ObservablesEnum["SelectionObservable"] = "selectionObservable";
|
|
27
|
+
ObservablesEnum["MouseMoveObservable"] = "mouseMoveObservable";
|
|
27
28
|
})(ObservablesEnum = exports.ObservablesEnum || (exports.ObservablesEnum = {}));
|
|
28
29
|
var autocapturePlugin = function (options, context) {
|
|
29
30
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autocapture-plugin.js","sourceRoot":"","sources":["../../src/autocapture-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport {\n type BrowserClient,\n type BrowserConfig,\n type EnrichmentPlugin,\n type ElementInteractionsOptions,\n DEFAULT_CSS_SELECTOR_ALLOWLIST,\n DEFAULT_ACTION_CLICK_ALLOWLIST,\n DEFAULT_DATA_ATTRIBUTE_PREFIX,\n IDiagnosticsClient,\n getGlobalScope,\n multicast,\n} from '@amplitude/analytics-core';\nimport { VERSION } from './version';\nimport * as constants from './constants';\nimport {\n createShouldTrackEvent,\n type ElementBasedTimestampedEvent,\n type TimestampedEvent,\n type NavigateEvent,\n} from './helpers';\nimport { WindowMessenger } from './libs/messenger';\nimport { trackClicks } from './autocapture/track-click';\nimport { trackChange } from './autocapture/track-change';\nimport { trackActionClick } from './autocapture/track-action-click';\nimport { createClickObservable, createMutationObservable } from './observables';\n\nimport {\n createLabeledEventToTriggerMap,\n createTriggerEvaluator,\n groupLabeledEventIdsByEventType,\n} from './pageActions/triggers';\nimport { DataExtractor } from './data-extractor';\nimport { Observable, Unsubscribable } from '@amplitude/analytics-core';\n\ntype NavigationType = {\n addEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;\n removeEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;\n};\n\ndeclare global {\n interface Window {\n navigation: NavigationType;\n }\n}\n\ntype BrowserEnrichmentPlugin = EnrichmentPlugin<BrowserClient, BrowserConfig>;\n\nexport type AutoCaptureOptionsWithDefaults = Required<\n Pick<ElementInteractionsOptions, 'debounceTime' | 'cssSelectorAllowlist' | 'actionClickAllowlist'>\n> &\n ElementInteractionsOptions;\n\nexport enum ObservablesEnum {\n ClickObservable = 'clickObservable',\n ChangeObservable = 'changeObservable',\n // ErrorObservable = 'errorObservable',\n NavigateObservable = 'navigateObservable',\n MutationObservable = 'mutationObservable',\n BrowserErrorObservable = 'browserErrorObservable',\n SelectionObservable = 'selectionObservable',\n}\n\nexport interface AllWindowObservables {\n [ObservablesEnum.ChangeObservable]: Observable<ElementBasedTimestampedEvent<Event>>;\n // [ObservablesEnum.ErrorObservable]: Observable<TimestampedEvent<ErrorEvent>>;\n [ObservablesEnum.ClickObservable]: Observable<ElementBasedTimestampedEvent<MouseEvent>>;\n [ObservablesEnum.MutationObservable]: Observable<TimestampedEvent<MutationRecord[]>>;\n [ObservablesEnum.NavigateObservable]?: Observable<TimestampedEvent<NavigateEvent>>;\n [ObservablesEnum.SelectionObservable]?: Observable<void>;\n}\n\nexport const autocapturePlugin = (\n options: ElementInteractionsOptions = {},\n context?: { diagnosticsClient: IDiagnosticsClient },\n): BrowserEnrichmentPlugin => {\n // Set the plugin version tag\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n context?.diagnosticsClient.setTag('plugin.autocapture.version', VERSION);\n\n const {\n dataAttributePrefix = DEFAULT_DATA_ATTRIBUTE_PREFIX,\n visualTaggingOptions = {\n enabled: true,\n messenger: new WindowMessenger(),\n },\n } = options;\n\n options.cssSelectorAllowlist = options.cssSelectorAllowlist ?? DEFAULT_CSS_SELECTOR_ALLOWLIST;\n options.actionClickAllowlist = options.actionClickAllowlist ?? DEFAULT_ACTION_CLICK_ALLOWLIST;\n options.debounceTime = options.debounceTime ?? 0;\n\n options.pageUrlExcludelist = options.pageUrlExcludelist?.reduce(\n (acc: (string | RegExp | { pattern: string })[], excludePattern) => {\n if (typeof excludePattern === 'string') {\n acc.push(excludePattern);\n }\n if (excludePattern instanceof RegExp) {\n acc.push(excludePattern);\n }\n if (typeof excludePattern === 'object' && excludePattern !== null && 'pattern' in excludePattern) {\n try {\n acc.push(new RegExp(excludePattern.pattern));\n } catch (regexError) {\n console.warn(`Invalid regex pattern: ${excludePattern.pattern}`, regexError);\n return acc;\n }\n }\n return acc;\n },\n [],\n );\n\n const name = constants.PLUGIN_NAME;\n const type = 'enrichment';\n\n const subscriptions: Unsubscribable[] = [];\n\n // Create data extractor based on options\n const dataExtractor = new DataExtractor(options, context);\n\n // Create observables on events on the window\n const createObservables = (): AllWindowObservables => {\n const clickObservable = multicast(\n createClickObservable().map(\n (click) =>\n dataExtractor.addAdditionalEventProperties(\n click,\n 'click',\n (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,\n dataAttributePrefix,\n ) as ElementBasedTimestampedEvent<MouseEvent>,\n ),\n );\n\n const changeObservable = multicast(\n new Observable<ElementBasedTimestampedEvent<Event>>((observer) => {\n const handler = (changeEvent: Event) => {\n const enrichedChangeEvent = dataExtractor.addAdditionalEventProperties(\n changeEvent,\n 'change',\n (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,\n dataAttributePrefix,\n ) as ElementBasedTimestampedEvent<Event>;\n observer.next(enrichedChangeEvent);\n };\n /* istanbul ignore next */\n getGlobalScope()?.document.addEventListener('change', handler, { capture: true });\n /* istanbul ignore next */\n return () => getGlobalScope()?.document.removeEventListener('change', handler);\n }),\n );\n\n // Create Observable from unhandled errors\n // const errorObservable = fromEvent<ErrorEvent>(window, 'error').pipe(\n // map((error) => addAdditionalEventProperties(error, 'error')),\n // );\n\n // Create observable for URL changes\n let navigateObservable: Observable<TimestampedEvent<NavigateEvent>> | undefined;\n\n /* istanbul ignore next */\n if (window.navigation) {\n navigateObservable = multicast(\n new Observable<TimestampedEvent<NavigateEvent>>((observer) => {\n const handler = (navigateEvent: NavigateEvent) => {\n const enrichedNavigateEvent = dataExtractor.addAdditionalEventProperties(\n navigateEvent,\n 'navigate',\n (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,\n dataAttributePrefix,\n );\n observer.next(enrichedNavigateEvent);\n };\n window.navigation.addEventListener('navigate', handler as EventListener);\n return () => {\n window.navigation.removeEventListener('navigate', handler as EventListener);\n };\n }),\n );\n }\n\n const mutationObservable = multicast(\n createMutationObservable().map((mutation) =>\n dataExtractor.addAdditionalEventProperties(\n mutation,\n 'mutation',\n (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,\n dataAttributePrefix,\n ),\n ),\n );\n\n return {\n [ObservablesEnum.ChangeObservable]: changeObservable,\n // [ObservablesEnum.ErrorObservable]: errorObservable,\n [ObservablesEnum.ClickObservable]: clickObservable,\n [ObservablesEnum.MutationObservable]: mutationObservable,\n [ObservablesEnum.NavigateObservable]: navigateObservable,\n };\n };\n\n // Group labeled events by event type (eg. click, change)\n let groupedLabeledEvents = groupLabeledEventIdsByEventType(Object.values(options.pageActions?.labeledEvents ?? {}));\n\n let labeledEventToTriggerMap = createLabeledEventToTriggerMap(options.pageActions?.triggers ?? []);\n\n // Evaluate triggers for the given event by running the actions associated with the matching triggers\n const evaluateTriggers = createTriggerEvaluator(\n groupedLabeledEvents,\n labeledEventToTriggerMap,\n dataExtractor,\n options,\n );\n\n // Function to recalculate internal variables when remote config is updated\n const recomputePageActionsData = (remotePageActions: ElementInteractionsOptions['pageActions']) => {\n if (remotePageActions) {\n // Merge remote config with local options\n options.pageActions = {\n ...options.pageActions,\n ...remotePageActions,\n };\n\n // Recalculate internal variables\n groupedLabeledEvents = groupLabeledEventIdsByEventType(Object.values(options.pageActions.labeledEvents ?? {}));\n labeledEventToTriggerMap = createLabeledEventToTriggerMap(options.pageActions.triggers ?? []);\n\n // Update evaluateTriggers function\n evaluateTriggers.update(groupedLabeledEvents, labeledEventToTriggerMap, options);\n }\n };\n\n const setup: BrowserEnrichmentPlugin['setup'] = async (config, amplitude) => {\n /* istanbul ignore if */\n if (typeof document === 'undefined') {\n return;\n }\n\n // Fetch remote config for pageActions in a non-blocking manner\n if (config.fetchRemoteConfig) {\n if (!config.remoteConfigClient) {\n // TODO(xinyi): Diagnostics.recordEvent\n config.loggerProvider.debug('Remote config client is not provided, skipping remote config fetch');\n } else {\n config.remoteConfigClient.subscribe('configs.analyticsSDK.pageActions', 'all', (remoteConfig) => {\n recomputePageActionsData(remoteConfig as ElementInteractionsOptions['pageActions']);\n });\n }\n }\n\n // Create should track event functions the different allowlists\n const shouldTrackEvent = createShouldTrackEvent(\n options,\n (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,\n );\n const shouldTrackActionClick = createShouldTrackEvent(\n options,\n (options as AutoCaptureOptionsWithDefaults).actionClickAllowlist,\n );\n\n // Create observables for events on the window\n const allObservables = createObservables();\n\n // Create subscriptions\n const clickTrackingSubscription = trackClicks({\n allObservables,\n amplitude,\n shouldTrackEvent: shouldTrackEvent,\n evaluateTriggers: evaluateTriggers.evaluate.bind(evaluateTriggers),\n });\n\n subscriptions.push(clickTrackingSubscription);\n\n const changeSubscription = trackChange({\n allObservables,\n getEventProperties: (...args) => dataExtractor.getEventProperties(...args, dataAttributePrefix),\n amplitude,\n shouldTrackEvent: shouldTrackEvent,\n evaluateTriggers: evaluateTriggers.evaluate.bind(evaluateTriggers),\n });\n subscriptions.push(changeSubscription);\n\n const actionClickSubscription = trackActionClick({\n allObservables,\n options: options as AutoCaptureOptionsWithDefaults,\n getEventProperties: (...args) => dataExtractor.getEventProperties(...args, dataAttributePrefix),\n amplitude,\n shouldTrackEvent,\n shouldTrackActionClick: shouldTrackActionClick,\n });\n if (actionClickSubscription) {\n subscriptions.push(actionClickSubscription);\n }\n\n /* istanbul ignore next */\n config?.loggerProvider?.log(`${name} has been successfully added.`);\n\n // Setup visual tagging selector\n if (window.opener && visualTaggingOptions.enabled) {\n const allowlist = (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist;\n const actionClickAllowlist = (options as AutoCaptureOptionsWithDefaults).actionClickAllowlist;\n\n /* istanbul ignore next */\n visualTaggingOptions.messenger?.setup({\n dataExtractor: dataExtractor,\n logger: config?.loggerProvider,\n ...(config?.serverZone && { endpoint: constants.AMPLITUDE_ORIGINS_MAP[config.serverZone] }),\n isElementSelectable: createShouldTrackEvent(options, [...allowlist, ...actionClickAllowlist]),\n cssSelectorAllowlist: allowlist,\n actionClickAllowlist: actionClickAllowlist,\n });\n }\n };\n\n const execute: BrowserEnrichmentPlugin['execute'] = async (event) => {\n return event;\n };\n\n const teardown = async () => {\n for (const subscription of subscriptions) {\n subscription.unsubscribe();\n }\n };\n\n return {\n name,\n type,\n setup,\n execute,\n teardown,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"autocapture-plugin.js","sourceRoot":"","sources":["../../src/autocapture-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport {\n type BrowserClient,\n type BrowserConfig,\n type EnrichmentPlugin,\n type ElementInteractionsOptions,\n DEFAULT_CSS_SELECTOR_ALLOWLIST,\n DEFAULT_ACTION_CLICK_ALLOWLIST,\n DEFAULT_DATA_ATTRIBUTE_PREFIX,\n IDiagnosticsClient,\n getGlobalScope,\n multicast,\n} from '@amplitude/analytics-core';\nimport { VERSION } from './version';\nimport * as constants from './constants';\nimport {\n createShouldTrackEvent,\n type ElementBasedTimestampedEvent,\n type TimestampedEvent,\n type NavigateEvent,\n} from './helpers';\nimport { WindowMessenger } from './libs/messenger';\nimport { trackClicks } from './autocapture/track-click';\nimport { trackChange } from './autocapture/track-change';\nimport { trackActionClick } from './autocapture/track-action-click';\nimport { createClickObservable, createMutationObservable } from './observables';\n\nimport {\n createLabeledEventToTriggerMap,\n createTriggerEvaluator,\n groupLabeledEventIdsByEventType,\n} from './pageActions/triggers';\nimport { DataExtractor } from './data-extractor';\nimport { Observable, Unsubscribable } from '@amplitude/analytics-core';\n\ntype NavigationType = {\n addEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;\n removeEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;\n};\n\ndeclare global {\n interface Window {\n navigation: NavigationType;\n }\n}\n\ntype BrowserEnrichmentPlugin = EnrichmentPlugin<BrowserClient, BrowserConfig>;\n\nexport type AutoCaptureOptionsWithDefaults = Required<\n Pick<ElementInteractionsOptions, 'debounceTime' | 'cssSelectorAllowlist' | 'actionClickAllowlist'>\n> &\n ElementInteractionsOptions;\n\nexport enum ObservablesEnum {\n ClickObservable = 'clickObservable',\n ChangeObservable = 'changeObservable',\n // ErrorObservable = 'errorObservable',\n NavigateObservable = 'navigateObservable',\n MutationObservable = 'mutationObservable',\n BrowserErrorObservable = 'browserErrorObservable',\n SelectionObservable = 'selectionObservable',\n MouseMoveObservable = 'mouseMoveObservable',\n}\n\nexport interface AllWindowObservables {\n [ObservablesEnum.ChangeObservable]: Observable<ElementBasedTimestampedEvent<Event>>;\n // [ObservablesEnum.ErrorObservable]: Observable<TimestampedEvent<ErrorEvent>>;\n [ObservablesEnum.ClickObservable]: Observable<ElementBasedTimestampedEvent<MouseEvent>>;\n [ObservablesEnum.MutationObservable]: Observable<TimestampedEvent<MutationRecord[]>>;\n [ObservablesEnum.NavigateObservable]?: Observable<TimestampedEvent<NavigateEvent>>;\n [ObservablesEnum.SelectionObservable]?: Observable<void>;\n}\n\nexport const autocapturePlugin = (\n options: ElementInteractionsOptions = {},\n context?: { diagnosticsClient: IDiagnosticsClient },\n): BrowserEnrichmentPlugin => {\n // Set the plugin version tag\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n context?.diagnosticsClient.setTag('plugin.autocapture.version', VERSION);\n\n const {\n dataAttributePrefix = DEFAULT_DATA_ATTRIBUTE_PREFIX,\n visualTaggingOptions = {\n enabled: true,\n messenger: new WindowMessenger(),\n },\n } = options;\n\n options.cssSelectorAllowlist = options.cssSelectorAllowlist ?? DEFAULT_CSS_SELECTOR_ALLOWLIST;\n options.actionClickAllowlist = options.actionClickAllowlist ?? DEFAULT_ACTION_CLICK_ALLOWLIST;\n options.debounceTime = options.debounceTime ?? 0;\n\n options.pageUrlExcludelist = options.pageUrlExcludelist?.reduce(\n (acc: (string | RegExp | { pattern: string })[], excludePattern) => {\n if (typeof excludePattern === 'string') {\n acc.push(excludePattern);\n }\n if (excludePattern instanceof RegExp) {\n acc.push(excludePattern);\n }\n if (typeof excludePattern === 'object' && excludePattern !== null && 'pattern' in excludePattern) {\n try {\n acc.push(new RegExp(excludePattern.pattern));\n } catch (regexError) {\n console.warn(`Invalid regex pattern: ${excludePattern.pattern}`, regexError);\n return acc;\n }\n }\n return acc;\n },\n [],\n );\n\n const name = constants.PLUGIN_NAME;\n const type = 'enrichment';\n\n const subscriptions: Unsubscribable[] = [];\n\n // Create data extractor based on options\n const dataExtractor = new DataExtractor(options, context);\n\n // Create observables on events on the window\n const createObservables = (): AllWindowObservables => {\n const clickObservable = multicast(\n createClickObservable().map(\n (click) =>\n dataExtractor.addAdditionalEventProperties(\n click,\n 'click',\n (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,\n dataAttributePrefix,\n ) as ElementBasedTimestampedEvent<MouseEvent>,\n ),\n );\n\n const changeObservable = multicast(\n new Observable<ElementBasedTimestampedEvent<Event>>((observer) => {\n const handler = (changeEvent: Event) => {\n const enrichedChangeEvent = dataExtractor.addAdditionalEventProperties(\n changeEvent,\n 'change',\n (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,\n dataAttributePrefix,\n ) as ElementBasedTimestampedEvent<Event>;\n observer.next(enrichedChangeEvent);\n };\n /* istanbul ignore next */\n getGlobalScope()?.document.addEventListener('change', handler, { capture: true });\n /* istanbul ignore next */\n return () => getGlobalScope()?.document.removeEventListener('change', handler);\n }),\n );\n\n // Create Observable from unhandled errors\n // const errorObservable = fromEvent<ErrorEvent>(window, 'error').pipe(\n // map((error) => addAdditionalEventProperties(error, 'error')),\n // );\n\n // Create observable for URL changes\n let navigateObservable: Observable<TimestampedEvent<NavigateEvent>> | undefined;\n\n /* istanbul ignore next */\n if (window.navigation) {\n navigateObservable = multicast(\n new Observable<TimestampedEvent<NavigateEvent>>((observer) => {\n const handler = (navigateEvent: NavigateEvent) => {\n const enrichedNavigateEvent = dataExtractor.addAdditionalEventProperties(\n navigateEvent,\n 'navigate',\n (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,\n dataAttributePrefix,\n );\n observer.next(enrichedNavigateEvent);\n };\n window.navigation.addEventListener('navigate', handler as EventListener);\n return () => {\n window.navigation.removeEventListener('navigate', handler as EventListener);\n };\n }),\n );\n }\n\n const mutationObservable = multicast(\n createMutationObservable().map((mutation) =>\n dataExtractor.addAdditionalEventProperties(\n mutation,\n 'mutation',\n (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,\n dataAttributePrefix,\n ),\n ),\n );\n\n return {\n [ObservablesEnum.ChangeObservable]: changeObservable,\n // [ObservablesEnum.ErrorObservable]: errorObservable,\n [ObservablesEnum.ClickObservable]: clickObservable,\n [ObservablesEnum.MutationObservable]: mutationObservable,\n [ObservablesEnum.NavigateObservable]: navigateObservable,\n };\n };\n\n // Group labeled events by event type (eg. click, change)\n let groupedLabeledEvents = groupLabeledEventIdsByEventType(Object.values(options.pageActions?.labeledEvents ?? {}));\n\n let labeledEventToTriggerMap = createLabeledEventToTriggerMap(options.pageActions?.triggers ?? []);\n\n // Evaluate triggers for the given event by running the actions associated with the matching triggers\n const evaluateTriggers = createTriggerEvaluator(\n groupedLabeledEvents,\n labeledEventToTriggerMap,\n dataExtractor,\n options,\n );\n\n // Function to recalculate internal variables when remote config is updated\n const recomputePageActionsData = (remotePageActions: ElementInteractionsOptions['pageActions']) => {\n if (remotePageActions) {\n // Merge remote config with local options\n options.pageActions = {\n ...options.pageActions,\n ...remotePageActions,\n };\n\n // Recalculate internal variables\n groupedLabeledEvents = groupLabeledEventIdsByEventType(Object.values(options.pageActions.labeledEvents ?? {}));\n labeledEventToTriggerMap = createLabeledEventToTriggerMap(options.pageActions.triggers ?? []);\n\n // Update evaluateTriggers function\n evaluateTriggers.update(groupedLabeledEvents, labeledEventToTriggerMap, options);\n }\n };\n\n const setup: BrowserEnrichmentPlugin['setup'] = async (config, amplitude) => {\n /* istanbul ignore if */\n if (typeof document === 'undefined') {\n return;\n }\n\n // Fetch remote config for pageActions in a non-blocking manner\n if (config.fetchRemoteConfig) {\n if (!config.remoteConfigClient) {\n // TODO(xinyi): Diagnostics.recordEvent\n config.loggerProvider.debug('Remote config client is not provided, skipping remote config fetch');\n } else {\n config.remoteConfigClient.subscribe('configs.analyticsSDK.pageActions', 'all', (remoteConfig) => {\n recomputePageActionsData(remoteConfig as ElementInteractionsOptions['pageActions']);\n });\n }\n }\n\n // Create should track event functions the different allowlists\n const shouldTrackEvent = createShouldTrackEvent(\n options,\n (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist,\n );\n const shouldTrackActionClick = createShouldTrackEvent(\n options,\n (options as AutoCaptureOptionsWithDefaults).actionClickAllowlist,\n );\n\n // Create observables for events on the window\n const allObservables = createObservables();\n\n // Create subscriptions\n const clickTrackingSubscription = trackClicks({\n allObservables,\n amplitude,\n shouldTrackEvent: shouldTrackEvent,\n evaluateTriggers: evaluateTriggers.evaluate.bind(evaluateTriggers),\n });\n\n subscriptions.push(clickTrackingSubscription);\n\n const changeSubscription = trackChange({\n allObservables,\n getEventProperties: (...args) => dataExtractor.getEventProperties(...args, dataAttributePrefix),\n amplitude,\n shouldTrackEvent: shouldTrackEvent,\n evaluateTriggers: evaluateTriggers.evaluate.bind(evaluateTriggers),\n });\n subscriptions.push(changeSubscription);\n\n const actionClickSubscription = trackActionClick({\n allObservables,\n options: options as AutoCaptureOptionsWithDefaults,\n getEventProperties: (...args) => dataExtractor.getEventProperties(...args, dataAttributePrefix),\n amplitude,\n shouldTrackEvent,\n shouldTrackActionClick: shouldTrackActionClick,\n });\n if (actionClickSubscription) {\n subscriptions.push(actionClickSubscription);\n }\n\n /* istanbul ignore next */\n config?.loggerProvider?.log(`${name} has been successfully added.`);\n\n // Setup visual tagging selector\n if (window.opener && visualTaggingOptions.enabled) {\n const allowlist = (options as AutoCaptureOptionsWithDefaults).cssSelectorAllowlist;\n const actionClickAllowlist = (options as AutoCaptureOptionsWithDefaults).actionClickAllowlist;\n\n /* istanbul ignore next */\n visualTaggingOptions.messenger?.setup({\n dataExtractor: dataExtractor,\n logger: config?.loggerProvider,\n ...(config?.serverZone && { endpoint: constants.AMPLITUDE_ORIGINS_MAP[config.serverZone] }),\n isElementSelectable: createShouldTrackEvent(options, [...allowlist, ...actionClickAllowlist]),\n cssSelectorAllowlist: allowlist,\n actionClickAllowlist: actionClickAllowlist,\n });\n }\n };\n\n const execute: BrowserEnrichmentPlugin['execute'] = async (event) => {\n return event;\n };\n\n const teardown = async () => {\n for (const subscription of subscriptions) {\n subscription.unsubscribe();\n }\n };\n\n return {\n name,\n type,\n setup,\n execute,\n teardown,\n };\n};\n"]}
|
package/lib/cjs/constants.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const AMPLITUDE_ELEMENT_DEAD_CLICKED_EVENT = "[Amplitude] Dead Cl
|
|
|
5
5
|
export declare const AMPLITUDE_ELEMENT_RAGE_CLICKED_EVENT = "[Amplitude] Rage Click";
|
|
6
6
|
export declare const AMPLITUDE_ELEMENT_ERROR_CLICKED_EVENT = "[Amplitude] Error Click";
|
|
7
7
|
export declare const AMPLITUDE_ELEMENT_CHANGED_EVENT = "[Amplitude] Element Changed";
|
|
8
|
+
export declare const AMPLITUDE_THRASHED_CURSOR_EVENT = "[Amplitude] Thrashed Cursor";
|
|
8
9
|
export declare const AMPLITUDE_EVENT_PROP_ELEMENT_ID = "[Amplitude] Element ID";
|
|
9
10
|
export declare const AMPLITUDE_EVENT_PROP_ELEMENT_CLASS = "[Amplitude] Element Class";
|
|
10
11
|
export declare const AMPLITUDE_EVENT_PROP_ELEMENT_TAG = "[Amplitude] Element Tag";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,0CAA0C,CAAC;AACnE,eAAO,MAAM,uBAAuB,0CAA0C,CAAC;AAE/E,eAAO,MAAM,+BAA+B,gCAAgC,CAAC;AAC7E,eAAO,MAAM,oCAAoC,2BAA2B,CAAC;AAC7E,eAAO,MAAM,oCAAoC,2BAA2B,CAAC;AAC7E,eAAO,MAAM,qCAAqC,4BAA4B,CAAC;AAC/E,eAAO,MAAM,+BAA+B,gCAAgC,CAAC;AAE7E,eAAO,MAAM,+BAA+B,2BAA2B,CAAC;AACxE,eAAO,MAAM,kCAAkC,8BAA8B,CAAC;AAC9E,eAAO,MAAM,gCAAgC,4BAA4B,CAAC;AAC1E,eAAO,MAAM,iCAAiC,6BAA6B,CAAC;AAC5E,eAAO,MAAM,sCAAsC,kCAAkC,CAAC;AACtF,eAAO,MAAM,iCAAiC,6BAA6B,CAAC;AAC5E,eAAO,MAAM,0CAA0C,sCAAsC,CAAC;AAC9F,eAAO,MAAM,yCAAyC,qCAAqC,CAAC;AAC5F,eAAO,MAAM,uCAAuC,mCAAmC,CAAC;AACxF,eAAO,MAAM,uCAAuC,mCAAmC,CAAC;AAExF,eAAO,MAAM,yCAAyC,qCAAqC,CAAC;AAC5F,eAAO,MAAM,6BAA6B,yBAAyB,CAAC;AACpE,eAAO,MAAM,+BAA+B,2BAA2B,CAAC;AACxE,eAAO,MAAM,oCAAoC,gCAAgC,CAAC;AAClF,eAAO,MAAM,mCAAmC,+BAA+B,CAAC;AAGhF,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAC5D,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAClE,eAAO,MAAM,wBAAwB,qCAAqC,CAAC;AAC3E,eAAO,MAAM,qBAAqB;;;;CAIjC,CAAC;AAEF,eAAO,MAAM,4CAA4C,6EACmB,CAAC;AAG7E,eAAO,MAAM,wCAAwC,0CAA0C,CAAC;AAGhG,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAEnE,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,oBAAoB,MAAM,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,0CAA0C,CAAC;AACnE,eAAO,MAAM,uBAAuB,0CAA0C,CAAC;AAE/E,eAAO,MAAM,+BAA+B,gCAAgC,CAAC;AAC7E,eAAO,MAAM,oCAAoC,2BAA2B,CAAC;AAC7E,eAAO,MAAM,oCAAoC,2BAA2B,CAAC;AAC7E,eAAO,MAAM,qCAAqC,4BAA4B,CAAC;AAC/E,eAAO,MAAM,+BAA+B,gCAAgC,CAAC;AAC7E,eAAO,MAAM,+BAA+B,gCAAgC,CAAC;AAE7E,eAAO,MAAM,+BAA+B,2BAA2B,CAAC;AACxE,eAAO,MAAM,kCAAkC,8BAA8B,CAAC;AAC9E,eAAO,MAAM,gCAAgC,4BAA4B,CAAC;AAC1E,eAAO,MAAM,iCAAiC,6BAA6B,CAAC;AAC5E,eAAO,MAAM,sCAAsC,kCAAkC,CAAC;AACtF,eAAO,MAAM,iCAAiC,6BAA6B,CAAC;AAC5E,eAAO,MAAM,0CAA0C,sCAAsC,CAAC;AAC9F,eAAO,MAAM,yCAAyC,qCAAqC,CAAC;AAC5F,eAAO,MAAM,uCAAuC,mCAAmC,CAAC;AACxF,eAAO,MAAM,uCAAuC,mCAAmC,CAAC;AAExF,eAAO,MAAM,yCAAyC,qCAAqC,CAAC;AAC5F,eAAO,MAAM,6BAA6B,yBAAyB,CAAC;AACpE,eAAO,MAAM,+BAA+B,2BAA2B,CAAC;AACxE,eAAO,MAAM,oCAAoC,gCAAgC,CAAC;AAClF,eAAO,MAAM,mCAAmC,+BAA+B,CAAC;AAGhF,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAC5D,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAClE,eAAO,MAAM,wBAAwB,qCAAqC,CAAC;AAC3E,eAAO,MAAM,qBAAqB;;;;CAIjC,CAAC;AAEF,eAAO,MAAM,4CAA4C,6EACmB,CAAC;AAG7E,eAAO,MAAM,wCAAwC,0CAA0C,CAAC;AAGhG,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAEnE,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,oBAAoB,MAAM,CAAC"}
|
package/lib/cjs/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MAX_ATTRIBUTE_LENGTH = exports.MAX_MASK_TEXT_PATTERNS = exports.DATA_AMP_MASK_ATTRIBUTES = exports.AMPLITUDE_VISUAL_TAGGING_HIGHLIGHT_CLASS = exports.AMPLITUDE_VISUAL_TAGGING_SELECTOR_SCRIPT_URL = exports.AMPLITUDE_ORIGINS_MAP = exports.AMPLITUDE_ORIGIN_STAGING = exports.AMPLITUDE_ORIGIN_EU = exports.AMPLITUDE_ORIGIN = exports.AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH = exports.AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT = exports.AMPLITUDE_EVENT_PROP_PAGE_TITLE = exports.AMPLITUDE_EVENT_PROP_PAGE_URL = exports.AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL = exports.AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES = exports.AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL = exports.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP = exports.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT = exports.AMPLITUDE_EVENT_PROP_ELEMENT_HREF = exports.AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY = exports.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT = exports.AMPLITUDE_EVENT_PROP_ELEMENT_TAG = exports.AMPLITUDE_EVENT_PROP_ELEMENT_CLASS = exports.AMPLITUDE_EVENT_PROP_ELEMENT_ID = exports.AMPLITUDE_ELEMENT_CHANGED_EVENT = exports.AMPLITUDE_ELEMENT_ERROR_CLICKED_EVENT = exports.AMPLITUDE_ELEMENT_RAGE_CLICKED_EVENT = exports.AMPLITUDE_ELEMENT_DEAD_CLICKED_EVENT = exports.AMPLITUDE_ELEMENT_CLICKED_EVENT = exports.FRUSTRATION_PLUGIN_NAME = exports.PLUGIN_NAME = void 0;
|
|
3
|
+
exports.MAX_ATTRIBUTE_LENGTH = exports.MAX_MASK_TEXT_PATTERNS = exports.DATA_AMP_MASK_ATTRIBUTES = exports.AMPLITUDE_VISUAL_TAGGING_HIGHLIGHT_CLASS = exports.AMPLITUDE_VISUAL_TAGGING_SELECTOR_SCRIPT_URL = exports.AMPLITUDE_ORIGINS_MAP = exports.AMPLITUDE_ORIGIN_STAGING = exports.AMPLITUDE_ORIGIN_EU = exports.AMPLITUDE_ORIGIN = exports.AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH = exports.AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT = exports.AMPLITUDE_EVENT_PROP_PAGE_TITLE = exports.AMPLITUDE_EVENT_PROP_PAGE_URL = exports.AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL = exports.AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES = exports.AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL = exports.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP = exports.AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT = exports.AMPLITUDE_EVENT_PROP_ELEMENT_HREF = exports.AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY = exports.AMPLITUDE_EVENT_PROP_ELEMENT_TEXT = exports.AMPLITUDE_EVENT_PROP_ELEMENT_TAG = exports.AMPLITUDE_EVENT_PROP_ELEMENT_CLASS = exports.AMPLITUDE_EVENT_PROP_ELEMENT_ID = exports.AMPLITUDE_THRASHED_CURSOR_EVENT = exports.AMPLITUDE_ELEMENT_CHANGED_EVENT = exports.AMPLITUDE_ELEMENT_ERROR_CLICKED_EVENT = exports.AMPLITUDE_ELEMENT_RAGE_CLICKED_EVENT = exports.AMPLITUDE_ELEMENT_DEAD_CLICKED_EVENT = exports.AMPLITUDE_ELEMENT_CLICKED_EVENT = exports.FRUSTRATION_PLUGIN_NAME = exports.PLUGIN_NAME = void 0;
|
|
4
4
|
exports.PLUGIN_NAME = '@amplitude/plugin-autocapture-browser';
|
|
5
5
|
exports.FRUSTRATION_PLUGIN_NAME = '@amplitude/plugin-frustration-browser';
|
|
6
6
|
exports.AMPLITUDE_ELEMENT_CLICKED_EVENT = '[Amplitude] Element Clicked';
|
|
@@ -8,6 +8,7 @@ exports.AMPLITUDE_ELEMENT_DEAD_CLICKED_EVENT = '[Amplitude] Dead Click';
|
|
|
8
8
|
exports.AMPLITUDE_ELEMENT_RAGE_CLICKED_EVENT = '[Amplitude] Rage Click';
|
|
9
9
|
exports.AMPLITUDE_ELEMENT_ERROR_CLICKED_EVENT = '[Amplitude] Error Click';
|
|
10
10
|
exports.AMPLITUDE_ELEMENT_CHANGED_EVENT = '[Amplitude] Element Changed';
|
|
11
|
+
exports.AMPLITUDE_THRASHED_CURSOR_EVENT = '[Amplitude] Thrashed Cursor';
|
|
11
12
|
exports.AMPLITUDE_EVENT_PROP_ELEMENT_ID = '[Amplitude] Element ID';
|
|
12
13
|
exports.AMPLITUDE_EVENT_PROP_ELEMENT_CLASS = '[Amplitude] Element Class';
|
|
13
14
|
exports.AMPLITUDE_EVENT_PROP_ELEMENT_TAG = '[Amplitude] Element Tag';
|
package/lib/cjs/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,WAAW,GAAG,uCAAuC,CAAC;AACtD,QAAA,uBAAuB,GAAG,uCAAuC,CAAC;AAElE,QAAA,+BAA+B,GAAG,6BAA6B,CAAC;AAChE,QAAA,oCAAoC,GAAG,wBAAwB,CAAC;AAChE,QAAA,oCAAoC,GAAG,wBAAwB,CAAC;AAChE,QAAA,qCAAqC,GAAG,yBAAyB,CAAC;AAClE,QAAA,+BAA+B,GAAG,6BAA6B,CAAC;AAEhE,QAAA,+BAA+B,GAAG,wBAAwB,CAAC;AAC3D,QAAA,kCAAkC,GAAG,2BAA2B,CAAC;AACjE,QAAA,gCAAgC,GAAG,yBAAyB,CAAC;AAC7D,QAAA,iCAAiC,GAAG,0BAA0B,CAAC;AAC/D,QAAA,sCAAsC,GAAG,+BAA+B,CAAC;AACzE,QAAA,iCAAiC,GAAG,0BAA0B,CAAC;AAC/D,QAAA,0CAA0C,GAAG,mCAAmC,CAAC;AACjF,QAAA,yCAAyC,GAAG,kCAAkC,CAAC;AAC/E,QAAA,uCAAuC,GAAG,gCAAgC,CAAC;AAC3E,QAAA,uCAAuC,GAAG,gCAAgC,CAAC;AAE3E,QAAA,yCAAyC,GAAG,kCAAkC,CAAC;AAC/E,QAAA,6BAA6B,GAAG,sBAAsB,CAAC;AACvD,QAAA,+BAA+B,GAAG,wBAAwB,CAAC;AAC3D,QAAA,oCAAoC,GAAG,6BAA6B,CAAC;AACrE,QAAA,mCAAmC,GAAG,4BAA4B,CAAC;AAEhF,mCAAmC;AACtB,QAAA,gBAAgB,GAAG,2BAA2B,CAAC;AAC/C,QAAA,mBAAmB,GAAG,8BAA8B,CAAC;AACrD,QAAA,wBAAwB,GAAG,kCAAkC,CAAC;AAC9D,QAAA,qBAAqB,GAAG;IACnC,EAAE,EAAE,wBAAgB;IACpB,EAAE,EAAE,2BAAmB;IACvB,OAAO,EAAE,gCAAwB;CAClC,CAAC;AAEW,QAAA,4CAA4C,GACvD,0EAA0E,CAAC;AAC7E,gGAAgG;AAChG,6CAA6C;AAChC,QAAA,wCAAwC,GAAG,uCAAuC,CAAC;AAEhG,qFAAqF;AACxE,QAAA,wBAAwB,GAAG,0BAA0B,CAAC;AAEtD,QAAA,sBAAsB,GAAG,EAAE,CAAC;AAC5B,QAAA,oBAAoB,GAAG,GAAG,CAAC","sourcesContent":["export const PLUGIN_NAME = '@amplitude/plugin-autocapture-browser';\nexport const FRUSTRATION_PLUGIN_NAME = '@amplitude/plugin-frustration-browser';\n\nexport const AMPLITUDE_ELEMENT_CLICKED_EVENT = '[Amplitude] Element Clicked';\nexport const AMPLITUDE_ELEMENT_DEAD_CLICKED_EVENT = '[Amplitude] Dead Click';\nexport const AMPLITUDE_ELEMENT_RAGE_CLICKED_EVENT = '[Amplitude] Rage Click';\nexport const AMPLITUDE_ELEMENT_ERROR_CLICKED_EVENT = '[Amplitude] Error Click';\nexport const AMPLITUDE_ELEMENT_CHANGED_EVENT = '[Amplitude] Element Changed';\n\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_ID = '[Amplitude] Element ID';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_CLASS = '[Amplitude] Element Class';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_TAG = '[Amplitude] Element Tag';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_TEXT = '[Amplitude] Element Text';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY = '[Amplitude] Element Hierarchy';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_HREF = '[Amplitude] Element Href';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT = '[Amplitude] Element Position Left';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP = '[Amplitude] Element Position Top';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL = '[Amplitude] Element Aria Label';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES = '[Amplitude] Element Attributes';\n\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL = '[Amplitude] Element Parent Label';\nexport const AMPLITUDE_EVENT_PROP_PAGE_URL = '[Amplitude] Page URL';\nexport const AMPLITUDE_EVENT_PROP_PAGE_TITLE = '[Amplitude] Page Title';\nexport const AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT = '[Amplitude] Viewport Height';\nexport const AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH = '[Amplitude] Viewport Width';\n\n// Visual Tagging related constants\nexport const AMPLITUDE_ORIGIN = 'https://app.amplitude.com';\nexport const AMPLITUDE_ORIGIN_EU = 'https://app.eu.amplitude.com';\nexport const AMPLITUDE_ORIGIN_STAGING = 'https://apps.stag2.amplitude.com';\nexport const AMPLITUDE_ORIGINS_MAP = {\n US: AMPLITUDE_ORIGIN,\n EU: AMPLITUDE_ORIGIN_EU,\n STAGING: AMPLITUDE_ORIGIN_STAGING,\n};\n\nexport const AMPLITUDE_VISUAL_TAGGING_SELECTOR_SCRIPT_URL =\n 'https://cdn.amplitude.com/libs/visual-tagging-selector-1.0.0-alpha.js.gz';\n// This is the class name used by the visual tagging selector to highlight the selected element.\n// Should not use this class in the selector.\nexport const AMPLITUDE_VISUAL_TAGGING_HIGHLIGHT_CLASS = 'amp-visual-tagging-selector-highlight';\n\n// Data attribute for specifying which attributes should be redacted from autocapture\nexport const DATA_AMP_MASK_ATTRIBUTES = 'data-amp-mask-attributes';\n\nexport const MAX_MASK_TEXT_PATTERNS = 25;\nexport const MAX_ATTRIBUTE_LENGTH = 128;\n"]}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,WAAW,GAAG,uCAAuC,CAAC;AACtD,QAAA,uBAAuB,GAAG,uCAAuC,CAAC;AAElE,QAAA,+BAA+B,GAAG,6BAA6B,CAAC;AAChE,QAAA,oCAAoC,GAAG,wBAAwB,CAAC;AAChE,QAAA,oCAAoC,GAAG,wBAAwB,CAAC;AAChE,QAAA,qCAAqC,GAAG,yBAAyB,CAAC;AAClE,QAAA,+BAA+B,GAAG,6BAA6B,CAAC;AAChE,QAAA,+BAA+B,GAAG,6BAA6B,CAAC;AAEhE,QAAA,+BAA+B,GAAG,wBAAwB,CAAC;AAC3D,QAAA,kCAAkC,GAAG,2BAA2B,CAAC;AACjE,QAAA,gCAAgC,GAAG,yBAAyB,CAAC;AAC7D,QAAA,iCAAiC,GAAG,0BAA0B,CAAC;AAC/D,QAAA,sCAAsC,GAAG,+BAA+B,CAAC;AACzE,QAAA,iCAAiC,GAAG,0BAA0B,CAAC;AAC/D,QAAA,0CAA0C,GAAG,mCAAmC,CAAC;AACjF,QAAA,yCAAyC,GAAG,kCAAkC,CAAC;AAC/E,QAAA,uCAAuC,GAAG,gCAAgC,CAAC;AAC3E,QAAA,uCAAuC,GAAG,gCAAgC,CAAC;AAE3E,QAAA,yCAAyC,GAAG,kCAAkC,CAAC;AAC/E,QAAA,6BAA6B,GAAG,sBAAsB,CAAC;AACvD,QAAA,+BAA+B,GAAG,wBAAwB,CAAC;AAC3D,QAAA,oCAAoC,GAAG,6BAA6B,CAAC;AACrE,QAAA,mCAAmC,GAAG,4BAA4B,CAAC;AAEhF,mCAAmC;AACtB,QAAA,gBAAgB,GAAG,2BAA2B,CAAC;AAC/C,QAAA,mBAAmB,GAAG,8BAA8B,CAAC;AACrD,QAAA,wBAAwB,GAAG,kCAAkC,CAAC;AAC9D,QAAA,qBAAqB,GAAG;IACnC,EAAE,EAAE,wBAAgB;IACpB,EAAE,EAAE,2BAAmB;IACvB,OAAO,EAAE,gCAAwB;CAClC,CAAC;AAEW,QAAA,4CAA4C,GACvD,0EAA0E,CAAC;AAC7E,gGAAgG;AAChG,6CAA6C;AAChC,QAAA,wCAAwC,GAAG,uCAAuC,CAAC;AAEhG,qFAAqF;AACxE,QAAA,wBAAwB,GAAG,0BAA0B,CAAC;AAEtD,QAAA,sBAAsB,GAAG,EAAE,CAAC;AAC5B,QAAA,oBAAoB,GAAG,GAAG,CAAC","sourcesContent":["export const PLUGIN_NAME = '@amplitude/plugin-autocapture-browser';\nexport const FRUSTRATION_PLUGIN_NAME = '@amplitude/plugin-frustration-browser';\n\nexport const AMPLITUDE_ELEMENT_CLICKED_EVENT = '[Amplitude] Element Clicked';\nexport const AMPLITUDE_ELEMENT_DEAD_CLICKED_EVENT = '[Amplitude] Dead Click';\nexport const AMPLITUDE_ELEMENT_RAGE_CLICKED_EVENT = '[Amplitude] Rage Click';\nexport const AMPLITUDE_ELEMENT_ERROR_CLICKED_EVENT = '[Amplitude] Error Click';\nexport const AMPLITUDE_ELEMENT_CHANGED_EVENT = '[Amplitude] Element Changed';\nexport const AMPLITUDE_THRASHED_CURSOR_EVENT = '[Amplitude] Thrashed Cursor';\n\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_ID = '[Amplitude] Element ID';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_CLASS = '[Amplitude] Element Class';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_TAG = '[Amplitude] Element Tag';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_TEXT = '[Amplitude] Element Text';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_HIERARCHY = '[Amplitude] Element Hierarchy';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_HREF = '[Amplitude] Element Href';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_LEFT = '[Amplitude] Element Position Left';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_POSITION_TOP = '[Amplitude] Element Position Top';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_ARIA_LABEL = '[Amplitude] Element Aria Label';\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_ATTRIBUTES = '[Amplitude] Element Attributes';\n\nexport const AMPLITUDE_EVENT_PROP_ELEMENT_PARENT_LABEL = '[Amplitude] Element Parent Label';\nexport const AMPLITUDE_EVENT_PROP_PAGE_URL = '[Amplitude] Page URL';\nexport const AMPLITUDE_EVENT_PROP_PAGE_TITLE = '[Amplitude] Page Title';\nexport const AMPLITUDE_EVENT_PROP_VIEWPORT_HEIGHT = '[Amplitude] Viewport Height';\nexport const AMPLITUDE_EVENT_PROP_VIEWPORT_WIDTH = '[Amplitude] Viewport Width';\n\n// Visual Tagging related constants\nexport const AMPLITUDE_ORIGIN = 'https://app.amplitude.com';\nexport const AMPLITUDE_ORIGIN_EU = 'https://app.eu.amplitude.com';\nexport const AMPLITUDE_ORIGIN_STAGING = 'https://apps.stag2.amplitude.com';\nexport const AMPLITUDE_ORIGINS_MAP = {\n US: AMPLITUDE_ORIGIN,\n EU: AMPLITUDE_ORIGIN_EU,\n STAGING: AMPLITUDE_ORIGIN_STAGING,\n};\n\nexport const AMPLITUDE_VISUAL_TAGGING_SELECTOR_SCRIPT_URL =\n 'https://cdn.amplitude.com/libs/visual-tagging-selector-1.0.0-alpha.js.gz';\n// This is the class name used by the visual tagging selector to highlight the selected element.\n// Should not use this class in the selector.\nexport const AMPLITUDE_VISUAL_TAGGING_HIGHLIGHT_CLASS = 'amp-visual-tagging-selector-highlight';\n\n// Data attribute for specifying which attributes should be redacted from autocapture\nexport const DATA_AMP_MASK_ATTRIBUTES = 'data-amp-mask-attributes';\n\nexport const MAX_MASK_TEXT_PATTERNS = 25;\nexport const MAX_ATTRIBUTE_LENGTH = 128;\n"]}
|
|
@@ -8,6 +8,7 @@ export interface AllWindowObservables {
|
|
|
8
8
|
[ObservablesEnum.BrowserErrorObservable]: Observable<TimestampedEvent<BrowserErrorEvent>>;
|
|
9
9
|
[ObservablesEnum.NavigateObservable]?: Observable<TimestampedEvent<NavigateEvent>>;
|
|
10
10
|
[ObservablesEnum.SelectionObservable]?: Observable<void>;
|
|
11
|
+
[ObservablesEnum.MouseMoveObservable]: Observable<MouseEvent>;
|
|
11
12
|
}
|
|
12
13
|
type BrowserEnrichmentPlugin = EnrichmentPlugin<BrowserClient, BrowserConfig>;
|
|
13
14
|
export declare const frustrationPlugin: (options?: FrustrationInteractionsOptions) => BrowserEnrichmentPlugin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frustration-plugin.d.ts","sourceRoot":"","sources":["../../src/frustration-plugin.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,8BAA8B,EAG9B,UAAU,EAKX,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAA0B,4BAA4B,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGlH,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EACL,iBAAiB,
|
|
1
|
+
{"version":3,"file":"frustration-plugin.d.ts","sourceRoot":"","sources":["../../src/frustration-plugin.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,8BAA8B,EAG9B,UAAU,EAKX,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAA0B,4BAA4B,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGlH,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EACL,iBAAiB,EAKlB,MAAM,eAAe,CAAC;AAKvB,MAAM,WAAW,oBAAoB;IACnC,CAAC,eAAe,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAAC;IACxF,CAAC,eAAe,CAAC,kBAAkB,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;IACrF,CAAC,eAAe,CAAC,sBAAsB,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC1F,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC,EAAE,UAAU,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC;IACnF,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC,eAAe,CAAC,mBAAmB,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;CAC/D;AAED,KAAK,uBAAuB,GAAG,gBAAgB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AA+B9E,eAAO,MAAM,iBAAiB,aAAa,8BAA8B,KAAQ,uBA0PhF,CAAC"}
|
|
@@ -12,6 +12,7 @@ var autocapture_plugin_1 = require("./autocapture-plugin");
|
|
|
12
12
|
var observables_1 = require("./observables");
|
|
13
13
|
var data_extractor_1 = require("./data-extractor");
|
|
14
14
|
var track_error_click_1 = require("./autocapture/track-error-click");
|
|
15
|
+
var track_thrashed_cursor_1 = require("./autocapture/track-thrashed-cursor");
|
|
15
16
|
/**
|
|
16
17
|
* Helper function to extract the css selector allowlist
|
|
17
18
|
* from the frustration interactions options for a specific
|
|
@@ -30,6 +31,8 @@ function getCssSelectorAllowlist(options, attribute, defaultAllowlist, enabled)
|
|
|
30
31
|
}
|
|
31
32
|
return defaultAllowlist;
|
|
32
33
|
}
|
|
34
|
+
var MINIMUM_THRASHED_CURSOR_DIRECTION_CHANGES = 5;
|
|
35
|
+
var MAXIMUM_THRASHED_CURSOR_THRESHOLD = 4000;
|
|
33
36
|
var frustrationPlugin = function (options) {
|
|
34
37
|
var _a;
|
|
35
38
|
if (options === void 0) { options = {}; }
|
|
@@ -45,6 +48,10 @@ var frustrationPlugin = function (options) {
|
|
|
45
48
|
// Check if each feature is enabled
|
|
46
49
|
var deadClicksEnabled = options.deadClicks !== false && options.deadClicks !== null;
|
|
47
50
|
var rageClicksEnabled = options.rageClicks !== false && options.rageClicks !== null;
|
|
51
|
+
var thrashedCursorEnabled = options.thrashedCursor !== false && options.thrashedCursor !== null;
|
|
52
|
+
if (!options.thrashedCursor) {
|
|
53
|
+
thrashedCursorEnabled = false;
|
|
54
|
+
}
|
|
48
55
|
// Get CSS selectors for enabled features
|
|
49
56
|
var rageCssSelectors = getCssSelectorAllowlist(options, 'rageClicks', analytics_core_1.DEFAULT_RAGE_CLICK_ALLOWLIST, rageClicksEnabled);
|
|
50
57
|
var deadCssSelectors = getCssSelectorAllowlist(options, 'deadClicks', analytics_core_1.DEFAULT_DEAD_CLICK_ALLOWLIST, deadClicksEnabled);
|
|
@@ -116,16 +123,18 @@ var frustrationPlugin = function (options) {
|
|
|
116
123
|
window.document.removeEventListener('selectionchange', handler);
|
|
117
124
|
};
|
|
118
125
|
}));
|
|
126
|
+
var mouseMoveObservable = (0, analytics_core_1.multicast)((0, observables_1.createMouseMoveObservable)());
|
|
119
127
|
return _a = {},
|
|
120
128
|
_a[autocapture_plugin_1.ObservablesEnum.ClickObservable] = clickObservable,
|
|
121
129
|
_a[autocapture_plugin_1.ObservablesEnum.MutationObservable] = enrichedMutationObservable,
|
|
122
130
|
_a[autocapture_plugin_1.ObservablesEnum.NavigateObservable] = enrichedNavigateObservable,
|
|
123
131
|
_a[autocapture_plugin_1.ObservablesEnum.BrowserErrorObservable] = browserErrorObservables,
|
|
124
132
|
_a[autocapture_plugin_1.ObservablesEnum.SelectionObservable] = selectionObservable,
|
|
133
|
+
_a[autocapture_plugin_1.ObservablesEnum.MouseMoveObservable] = mouseMoveObservable,
|
|
125
134
|
_a;
|
|
126
135
|
};
|
|
127
136
|
var setup = function (config, amplitude) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
128
|
-
var allObservables, shouldTrackRageClick, rageClickSubscription, shouldTrackDeadClick, deadClickSubscription, shouldTrackErrorClick, errorClickSubscription;
|
|
137
|
+
var allObservables, shouldTrackRageClick, rageClickSubscription, shouldTrackDeadClick, deadClickSubscription, shouldTrackErrorClick, errorClickSubscription, directionChanges, thresholdMs, thrashedCursorSubscription;
|
|
129
138
|
var _a;
|
|
130
139
|
return tslib_1.__generator(this, function (_b) {
|
|
131
140
|
/* istanbul ignore if */
|
|
@@ -164,6 +173,29 @@ var frustrationPlugin = function (options) {
|
|
|
164
173
|
});
|
|
165
174
|
subscriptions.push(errorClickSubscription);
|
|
166
175
|
}
|
|
176
|
+
if (thrashedCursorEnabled) {
|
|
177
|
+
directionChanges = void 0, thresholdMs = void 0;
|
|
178
|
+
if (typeof options.thrashedCursor === 'object') {
|
|
179
|
+
directionChanges = options.thrashedCursor.directionChanges;
|
|
180
|
+
thresholdMs = options.thrashedCursor.threshold;
|
|
181
|
+
if (directionChanges && directionChanges < MINIMUM_THRASHED_CURSOR_DIRECTION_CHANGES) {
|
|
182
|
+
config.loggerProvider.warn("'thrashedCursor.directionChanges' of ".concat(directionChanges, " is below the minimum of ").concat(MINIMUM_THRASHED_CURSOR_DIRECTION_CHANGES, ", setting to ").concat(MINIMUM_THRASHED_CURSOR_DIRECTION_CHANGES));
|
|
183
|
+
directionChanges = MINIMUM_THRASHED_CURSOR_DIRECTION_CHANGES;
|
|
184
|
+
}
|
|
185
|
+
if (thresholdMs && thresholdMs > MAXIMUM_THRASHED_CURSOR_THRESHOLD) {
|
|
186
|
+
config.loggerProvider.warn("'thrashedCursor.threshold' of ".concat(thresholdMs, " is above the maximum of ").concat(MAXIMUM_THRASHED_CURSOR_THRESHOLD, ", setting to ").concat(MAXIMUM_THRASHED_CURSOR_THRESHOLD));
|
|
187
|
+
thresholdMs = MAXIMUM_THRASHED_CURSOR_THRESHOLD;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
thrashedCursorSubscription = (0, track_thrashed_cursor_1.trackThrashedCursor)({
|
|
191
|
+
amplitude: amplitude,
|
|
192
|
+
options: options,
|
|
193
|
+
allObservables: allObservables,
|
|
194
|
+
directionChanges: directionChanges,
|
|
195
|
+
thresholdMs: thresholdMs,
|
|
196
|
+
});
|
|
197
|
+
subscriptions.push(thrashedCursorSubscription);
|
|
198
|
+
}
|
|
167
199
|
/* istanbul ignore next */
|
|
168
200
|
(_a = config === null || config === void 0 ? void 0 : config.loggerProvider) === null || _a === void 0 ? void 0 : _a.log("".concat(name, " has been successfully added."));
|
|
169
201
|
return [2 /*return*/];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frustration-plugin.js","sourceRoot":"","sources":["../../src/frustration-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport {\n BrowserClient,\n BrowserConfig,\n EnrichmentPlugin,\n FrustrationInteractionsOptions,\n DEFAULT_DATA_ATTRIBUTE_PREFIX,\n multicast,\n Observable,\n Unsubscribable,\n DEFAULT_RAGE_CLICK_ALLOWLIST,\n DEFAULT_DEAD_CLICK_ALLOWLIST,\n DEFAULT_ERROR_CLICK_ALLOWLIST,\n} from '@amplitude/analytics-core';\nimport * as constants from './constants';\nimport { createShouldTrackEvent, ElementBasedTimestampedEvent, NavigateEvent, TimestampedEvent } from './helpers';\nimport { trackDeadClick } from './autocapture/track-dead-click';\nimport { trackRageClicks } from './autocapture/track-rage-click';\nimport { ObservablesEnum } from './autocapture-plugin';\nimport {\n BrowserErrorEvent,\n createClickObservable,\n createErrorObservable,\n createMutationObservable,\n} from './observables';\nimport { DataExtractor } from './data-extractor';\nimport { trackErrorClicks } from './autocapture/track-error-click';\n\nexport interface AllWindowObservables {\n [ObservablesEnum.ClickObservable]: Observable<ElementBasedTimestampedEvent<MouseEvent>>;\n [ObservablesEnum.MutationObservable]: Observable<TimestampedEvent<MutationRecord[]>>;\n [ObservablesEnum.BrowserErrorObservable]: Observable<TimestampedEvent<BrowserErrorEvent>>;\n [ObservablesEnum.NavigateObservable]?: Observable<TimestampedEvent<NavigateEvent>>;\n [ObservablesEnum.SelectionObservable]?: Observable<void>;\n}\n\ntype BrowserEnrichmentPlugin = EnrichmentPlugin<BrowserClient, BrowserConfig>;\n\n/**\n * Helper function to extract the css selector allowlist\n * from the frustration interactions options for a specific\n * autocapture feature.\n */\nfunction getCssSelectorAllowlist(\n options: FrustrationInteractionsOptions,\n attribute: keyof FrustrationInteractionsOptions,\n defaultAllowlist: string[],\n enabled: boolean,\n): string[] {\n if (!enabled) {\n return [];\n }\n const config = options[attribute];\n if (\n typeof config === 'object' &&\n config !== null &&\n 'cssSelectorAllowlist' in config &&\n Array.isArray(config.cssSelectorAllowlist)\n ) {\n return config.cssSelectorAllowlist;\n }\n return defaultAllowlist;\n}\n\nexport const frustrationPlugin = (options: FrustrationInteractionsOptions = {}): BrowserEnrichmentPlugin => {\n const name = constants.FRUSTRATION_PLUGIN_NAME;\n const type = 'enrichment';\n\n const subscriptions: Unsubscribable[] = [];\n\n let isErrorClicksEnabled = options.errorClicks !== false;\n\n // if errorClicks is not defined, disable it\n // change this once it moves out of @experimental\n if (!options.errorClicks) {\n isErrorClicksEnabled = false;\n }\n\n // Check if each feature is enabled\n const deadClicksEnabled = options.deadClicks !== false && options.deadClicks !== null;\n const rageClicksEnabled = options.rageClicks !== false && options.rageClicks !== null;\n\n // Get CSS selectors for enabled features\n const rageCssSelectors = getCssSelectorAllowlist(\n options,\n 'rageClicks',\n DEFAULT_RAGE_CLICK_ALLOWLIST,\n rageClicksEnabled,\n );\n const deadCssSelectors = getCssSelectorAllowlist(\n options,\n 'deadClicks',\n DEFAULT_DEAD_CLICK_ALLOWLIST,\n deadClicksEnabled,\n );\n\n const errorCssSelectors = getCssSelectorAllowlist(\n options,\n 'errorClicks',\n DEFAULT_ERROR_CLICK_ALLOWLIST,\n isErrorClicksEnabled,\n );\n\n const dataAttributePrefix = options.dataAttributePrefix ?? DEFAULT_DATA_ATTRIBUTE_PREFIX;\n\n const dataExtractor = new DataExtractor(options);\n\n // combine the selector lists from enabled features to determine which clicked elements should be filtered\n const combinedCssSelectors = [...new Set([...rageCssSelectors, ...deadCssSelectors, ...errorCssSelectors])];\n\n // Create observables on events on the window\n const createObservables = (): AllWindowObservables => {\n const clickObservable = multicast(\n createClickObservable('pointerdown').map((click) => {\n return dataExtractor.addAdditionalEventProperties(\n click,\n 'click',\n combinedCssSelectors,\n dataAttributePrefix,\n true, // capture when cursor is pointer\n );\n }),\n );\n\n const browserErrorObservables = multicast(\n createErrorObservable().map((error) => {\n return dataExtractor.addTypeAndTimestamp(error, 'error');\n }),\n );\n\n const enrichedMutationObservable = multicast<TimestampedEvent<MutationRecord[]>>(\n createMutationObservable().map((mutation) =>\n dataExtractor.addAdditionalEventProperties(mutation, 'mutation', combinedCssSelectors, dataAttributePrefix),\n ),\n );\n\n let enrichedNavigateObservable: Observable<TimestampedEvent<NavigateEvent>> | undefined;\n\n if (window.navigation) {\n const navigateObservable = new Observable<Event>((observer) => {\n const handler = (event: Event): void => {\n observer.next({\n ...event,\n type: 'navigate',\n });\n };\n window.navigation.addEventListener('navigate', handler);\n return () => {\n window.navigation.removeEventListener('navigate', handler);\n };\n });\n enrichedNavigateObservable = multicast<TimestampedEvent<NavigateEvent>>(\n navigateObservable.map<TimestampedEvent<NavigateEvent>>(\n (navigate) =>\n dataExtractor.addAdditionalEventProperties(\n navigate,\n 'navigate',\n combinedCssSelectors,\n dataAttributePrefix,\n ) as TimestampedEvent<NavigateEvent>,\n ),\n );\n }\n\n const selectionObservable = multicast(\n new Observable<void>((observer) => {\n const handler = () => {\n const el: HTMLElement | null = document.activeElement as HTMLElement;\n\n // handle input and textarea\n\n // if the selectionStart and selectionEnd are the same, it means\n // nothing is selected (collapsed) and the cursor position is one point\n if (el && (el.tagName === 'TEXTAREA' || el.tagName === 'INPUT')) {\n let start: number | null | undefined;\n let end: number | null | undefined;\n try {\n start = (el as HTMLInputElement | HTMLTextAreaElement).selectionStart;\n end = (el as HTMLInputElement | HTMLTextAreaElement).selectionEnd;\n if (start === end) return; // collapsed\n } catch (error) {\n // input that doesn't support selectionStart/selectionEnd (like checkbox)\n // do nothing here\n return;\n }\n return observer.next();\n }\n\n // handle non-input elements\n\n // non-input elements have an attribute called \"isCollapsed\" which\n // if true, indicates there \"is currently not any text selected\"\n // (see https://developer.mozilla.org/en-US/docs/Web/API/Selection/isCollapsed)\n const selection = window.getSelection();\n if (!selection || selection.isCollapsed) return;\n return observer.next();\n };\n window.document.addEventListener('selectionchange', handler);\n return () => {\n window.document.removeEventListener('selectionchange', handler);\n };\n }),\n );\n\n return {\n [ObservablesEnum.ClickObservable]: clickObservable as Observable<ElementBasedTimestampedEvent<MouseEvent>>,\n [ObservablesEnum.MutationObservable]: enrichedMutationObservable,\n [ObservablesEnum.NavigateObservable]: enrichedNavigateObservable,\n [ObservablesEnum.BrowserErrorObservable]: browserErrorObservables,\n [ObservablesEnum.SelectionObservable]: selectionObservable,\n };\n };\n\n const setup: BrowserEnrichmentPlugin['setup'] = async (config, amplitude) => {\n /* istanbul ignore if */\n if (typeof document === 'undefined') {\n return;\n }\n\n // Create observables for events on the window\n const allObservables = createObservables();\n\n // Create subscriptions only for enabled features\n if (rageClicksEnabled) {\n const shouldTrackRageClick = createShouldTrackEvent(options, rageCssSelectors);\n const rageClickSubscription = trackRageClicks({\n allObservables,\n amplitude,\n shouldTrackRageClick,\n });\n subscriptions.push(rageClickSubscription);\n }\n\n if (deadClicksEnabled) {\n const shouldTrackDeadClick = createShouldTrackEvent(options, deadCssSelectors);\n const deadClickSubscription = trackDeadClick({\n amplitude,\n allObservables,\n getEventProperties: (actionType, element) =>\n dataExtractor.getEventProperties(actionType, element, dataAttributePrefix),\n shouldTrackDeadClick,\n });\n subscriptions.push(deadClickSubscription);\n }\n\n if (isErrorClicksEnabled) {\n const shouldTrackErrorClick = createShouldTrackEvent(options, errorCssSelectors);\n const errorClickSubscription = trackErrorClicks({\n amplitude,\n allObservables,\n shouldTrackErrorClick,\n });\n subscriptions.push(errorClickSubscription);\n }\n\n /* istanbul ignore next */\n config?.loggerProvider?.log(`${name} has been successfully added.`);\n };\n\n const execute: BrowserEnrichmentPlugin['execute'] = async (event) => {\n return event;\n };\n\n const teardown = async () => {\n for (const subscription of subscriptions) {\n subscription.unsubscribe();\n }\n };\n\n return {\n name,\n type,\n setup,\n execute,\n teardown,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"frustration-plugin.js","sourceRoot":"","sources":["../../src/frustration-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-restricted-globals */\nimport {\n BrowserClient,\n BrowserConfig,\n EnrichmentPlugin,\n FrustrationInteractionsOptions,\n DEFAULT_DATA_ATTRIBUTE_PREFIX,\n multicast,\n Observable,\n Unsubscribable,\n DEFAULT_RAGE_CLICK_ALLOWLIST,\n DEFAULT_DEAD_CLICK_ALLOWLIST,\n DEFAULT_ERROR_CLICK_ALLOWLIST,\n} from '@amplitude/analytics-core';\nimport * as constants from './constants';\nimport { createShouldTrackEvent, ElementBasedTimestampedEvent, NavigateEvent, TimestampedEvent } from './helpers';\nimport { trackDeadClick } from './autocapture/track-dead-click';\nimport { trackRageClicks } from './autocapture/track-rage-click';\nimport { ObservablesEnum } from './autocapture-plugin';\nimport {\n BrowserErrorEvent,\n createClickObservable,\n createErrorObservable,\n createMutationObservable,\n createMouseMoveObservable,\n} from './observables';\nimport { DataExtractor } from './data-extractor';\nimport { trackErrorClicks } from './autocapture/track-error-click';\nimport { trackThrashedCursor } from './autocapture/track-thrashed-cursor';\n\nexport interface AllWindowObservables {\n [ObservablesEnum.ClickObservable]: Observable<ElementBasedTimestampedEvent<MouseEvent>>;\n [ObservablesEnum.MutationObservable]: Observable<TimestampedEvent<MutationRecord[]>>;\n [ObservablesEnum.BrowserErrorObservable]: Observable<TimestampedEvent<BrowserErrorEvent>>;\n [ObservablesEnum.NavigateObservable]?: Observable<TimestampedEvent<NavigateEvent>>;\n [ObservablesEnum.SelectionObservable]?: Observable<void>;\n [ObservablesEnum.MouseMoveObservable]: Observable<MouseEvent>;\n}\n\ntype BrowserEnrichmentPlugin = EnrichmentPlugin<BrowserClient, BrowserConfig>;\n\n/**\n * Helper function to extract the css selector allowlist\n * from the frustration interactions options for a specific\n * autocapture feature.\n */\nfunction getCssSelectorAllowlist(\n options: FrustrationInteractionsOptions,\n attribute: keyof FrustrationInteractionsOptions,\n defaultAllowlist: string[],\n enabled: boolean,\n): string[] {\n if (!enabled) {\n return [];\n }\n const config = options[attribute];\n if (\n typeof config === 'object' &&\n config !== null &&\n 'cssSelectorAllowlist' in config &&\n Array.isArray(config.cssSelectorAllowlist)\n ) {\n return config.cssSelectorAllowlist;\n }\n return defaultAllowlist;\n}\n\nconst MINIMUM_THRASHED_CURSOR_DIRECTION_CHANGES = 5;\nconst MAXIMUM_THRASHED_CURSOR_THRESHOLD = 4000;\n\nexport const frustrationPlugin = (options: FrustrationInteractionsOptions = {}): BrowserEnrichmentPlugin => {\n const name = constants.FRUSTRATION_PLUGIN_NAME;\n const type = 'enrichment';\n\n const subscriptions: Unsubscribable[] = [];\n\n let isErrorClicksEnabled = options.errorClicks !== false;\n\n // if errorClicks is not defined, disable it\n // change this once it moves out of @experimental\n if (!options.errorClicks) {\n isErrorClicksEnabled = false;\n }\n\n // Check if each feature is enabled\n const deadClicksEnabled = options.deadClicks !== false && options.deadClicks !== null;\n const rageClicksEnabled = options.rageClicks !== false && options.rageClicks !== null;\n\n let thrashedCursorEnabled = options.thrashedCursor !== false && options.thrashedCursor !== null;\n if (!options.thrashedCursor) {\n thrashedCursorEnabled = false;\n }\n\n // Get CSS selectors for enabled features\n const rageCssSelectors = getCssSelectorAllowlist(\n options,\n 'rageClicks',\n DEFAULT_RAGE_CLICK_ALLOWLIST,\n rageClicksEnabled,\n );\n\n const deadCssSelectors = getCssSelectorAllowlist(\n options,\n 'deadClicks',\n DEFAULT_DEAD_CLICK_ALLOWLIST,\n deadClicksEnabled,\n );\n\n const errorCssSelectors = getCssSelectorAllowlist(\n options,\n 'errorClicks',\n DEFAULT_ERROR_CLICK_ALLOWLIST,\n isErrorClicksEnabled,\n );\n\n const dataAttributePrefix = options.dataAttributePrefix ?? DEFAULT_DATA_ATTRIBUTE_PREFIX;\n\n const dataExtractor = new DataExtractor(options);\n\n // combine the selector lists from enabled features to determine which clicked elements should be filtered\n const combinedCssSelectors = [...new Set([...rageCssSelectors, ...deadCssSelectors, ...errorCssSelectors])];\n\n // Create observables on events on the window\n const createObservables = (): AllWindowObservables => {\n const clickObservable = multicast(\n createClickObservable('pointerdown').map((click) => {\n return dataExtractor.addAdditionalEventProperties(\n click,\n 'click',\n combinedCssSelectors,\n dataAttributePrefix,\n true, // capture when cursor is pointer\n );\n }),\n );\n\n const browserErrorObservables = multicast(\n createErrorObservable().map((error) => {\n return dataExtractor.addTypeAndTimestamp(error, 'error');\n }),\n );\n\n const enrichedMutationObservable = multicast<TimestampedEvent<MutationRecord[]>>(\n createMutationObservable().map((mutation) =>\n dataExtractor.addAdditionalEventProperties(mutation, 'mutation', combinedCssSelectors, dataAttributePrefix),\n ),\n );\n\n let enrichedNavigateObservable: Observable<TimestampedEvent<NavigateEvent>> | undefined;\n\n if (window.navigation) {\n const navigateObservable = new Observable<Event>((observer) => {\n const handler = (event: Event): void => {\n observer.next({\n ...event,\n type: 'navigate',\n });\n };\n window.navigation.addEventListener('navigate', handler);\n return () => {\n window.navigation.removeEventListener('navigate', handler);\n };\n });\n enrichedNavigateObservable = multicast<TimestampedEvent<NavigateEvent>>(\n navigateObservable.map<TimestampedEvent<NavigateEvent>>(\n (navigate) =>\n dataExtractor.addAdditionalEventProperties(\n navigate,\n 'navigate',\n combinedCssSelectors,\n dataAttributePrefix,\n ) as TimestampedEvent<NavigateEvent>,\n ),\n );\n }\n\n const selectionObservable = multicast(\n new Observable<void>((observer) => {\n const handler = () => {\n const el: HTMLElement | null = document.activeElement as HTMLElement;\n\n // handle input and textarea\n\n // if the selectionStart and selectionEnd are the same, it means\n // nothing is selected (collapsed) and the cursor position is one point\n if (el && (el.tagName === 'TEXTAREA' || el.tagName === 'INPUT')) {\n let start: number | null | undefined;\n let end: number | null | undefined;\n try {\n start = (el as HTMLInputElement | HTMLTextAreaElement).selectionStart;\n end = (el as HTMLInputElement | HTMLTextAreaElement).selectionEnd;\n if (start === end) return; // collapsed\n } catch (error) {\n // input that doesn't support selectionStart/selectionEnd (like checkbox)\n // do nothing here\n return;\n }\n return observer.next();\n }\n\n // handle non-input elements\n\n // non-input elements have an attribute called \"isCollapsed\" which\n // if true, indicates there \"is currently not any text selected\"\n // (see https://developer.mozilla.org/en-US/docs/Web/API/Selection/isCollapsed)\n const selection = window.getSelection();\n if (!selection || selection.isCollapsed) return;\n return observer.next();\n };\n window.document.addEventListener('selectionchange', handler);\n return () => {\n window.document.removeEventListener('selectionchange', handler);\n };\n }),\n );\n\n const mouseMoveObservable = multicast(createMouseMoveObservable());\n\n return {\n [ObservablesEnum.ClickObservable]: clickObservable as Observable<ElementBasedTimestampedEvent<MouseEvent>>,\n [ObservablesEnum.MutationObservable]: enrichedMutationObservable,\n [ObservablesEnum.NavigateObservable]: enrichedNavigateObservable,\n [ObservablesEnum.BrowserErrorObservable]: browserErrorObservables,\n [ObservablesEnum.SelectionObservable]: selectionObservable,\n [ObservablesEnum.MouseMoveObservable]: mouseMoveObservable,\n };\n };\n\n const setup: BrowserEnrichmentPlugin['setup'] = async (config, amplitude) => {\n /* istanbul ignore if */\n if (typeof document === 'undefined') {\n return;\n }\n\n // Create observables for events on the window\n const allObservables = createObservables();\n\n // Create subscriptions only for enabled features\n if (rageClicksEnabled) {\n const shouldTrackRageClick = createShouldTrackEvent(options, rageCssSelectors);\n const rageClickSubscription = trackRageClicks({\n allObservables,\n amplitude,\n shouldTrackRageClick,\n });\n subscriptions.push(rageClickSubscription);\n }\n\n if (deadClicksEnabled) {\n const shouldTrackDeadClick = createShouldTrackEvent(options, deadCssSelectors);\n const deadClickSubscription = trackDeadClick({\n amplitude,\n allObservables,\n getEventProperties: (actionType, element) =>\n dataExtractor.getEventProperties(actionType, element, dataAttributePrefix),\n shouldTrackDeadClick,\n });\n subscriptions.push(deadClickSubscription);\n }\n\n if (isErrorClicksEnabled) {\n const shouldTrackErrorClick = createShouldTrackEvent(options, errorCssSelectors);\n const errorClickSubscription = trackErrorClicks({\n amplitude,\n allObservables,\n shouldTrackErrorClick,\n });\n subscriptions.push(errorClickSubscription);\n }\n\n if (thrashedCursorEnabled) {\n let directionChanges, thresholdMs;\n if (typeof options.thrashedCursor === 'object') {\n directionChanges = options.thrashedCursor.directionChanges;\n thresholdMs = options.thrashedCursor.threshold;\n\n if (directionChanges && directionChanges < MINIMUM_THRASHED_CURSOR_DIRECTION_CHANGES) {\n config.loggerProvider.warn(\n `'thrashedCursor.directionChanges' of ${directionChanges} is below the minimum of ${MINIMUM_THRASHED_CURSOR_DIRECTION_CHANGES}, setting to ${MINIMUM_THRASHED_CURSOR_DIRECTION_CHANGES}`,\n );\n directionChanges = MINIMUM_THRASHED_CURSOR_DIRECTION_CHANGES;\n }\n if (thresholdMs && thresholdMs > MAXIMUM_THRASHED_CURSOR_THRESHOLD) {\n config.loggerProvider.warn(\n `'thrashedCursor.threshold' of ${thresholdMs} is above the maximum of ${MAXIMUM_THRASHED_CURSOR_THRESHOLD}, setting to ${MAXIMUM_THRASHED_CURSOR_THRESHOLD}`,\n );\n thresholdMs = MAXIMUM_THRASHED_CURSOR_THRESHOLD;\n }\n }\n const thrashedCursorSubscription = trackThrashedCursor({\n amplitude,\n options,\n allObservables,\n directionChanges,\n thresholdMs,\n });\n subscriptions.push(thrashedCursorSubscription);\n }\n\n /* istanbul ignore next */\n config?.loggerProvider?.log(`${name} has been successfully added.`);\n };\n\n const execute: BrowserEnrichmentPlugin['execute'] = async (event) => {\n return event;\n };\n\n const teardown = async () => {\n for (const subscription of subscriptions) {\n subscription.unsubscribe();\n }\n };\n\n return {\n name,\n type,\n setup,\n execute,\n teardown,\n };\n};\n"]}
|