@croct/sdk 0.21.0 → 0.22.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/apiKey.cjs +3 -3
- package/apiKey.js +3 -3
- package/constants.cjs +1 -1
- package/constants.d.cts +2 -2
- package/constants.d.ts +2 -2
- package/constants.js +1 -1
- package/container.cjs +8 -1
- package/container.d.cts +2 -0
- package/container.d.ts +2 -0
- package/container.js +8 -1
- package/facade/evaluatorFacade.cjs +4 -4
- package/facade/evaluatorFacade.d.cts +2 -1
- package/facade/evaluatorFacade.d.ts +2 -1
- package/facade/evaluatorFacade.js +4 -4
- package/facade/sdkFacade.cjs +8 -2
- package/facade/sdkFacade.js +8 -2
- package/interactionMonitor.cjs +181 -0
- package/interactionMonitor.d.cts +64 -0
- package/interactionMonitor.d.ts +64 -0
- package/interactionMonitor.js +158 -0
- package/package.json +1 -1
- package/schema/eventSchemas.cjs +46 -0
- package/schema/eventSchemas.d.cts +3 -1
- package/schema/eventSchemas.d.ts +3 -1
- package/schema/eventSchemas.js +44 -0
- package/schema/index.d.cts +1 -1
- package/schema/index.d.ts +1 -1
- package/sdk.cjs +3 -0
- package/sdk.d.cts +1 -0
- package/sdk.d.ts +1 -0
- package/sdk.js +3 -0
- package/tracker.cjs +9 -1
- package/tracker.d.cts +3 -0
- package/tracker.d.ts +3 -0
- package/tracker.js +9 -1
- package/trackingEvents.cjs +7 -0
- package/trackingEvents.d.cts +27 -2
- package/trackingEvents.d.ts +27 -2
- package/trackingEvents.js +6 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { SynchronousEventManager } from "./eventManager.js";
|
|
2
|
+
class InteractionMonitor {
|
|
3
|
+
constructor(options = {}) {
|
|
4
|
+
this.eventManager = new SynchronousEventManager();
|
|
5
|
+
this.lastClickTime = 0;
|
|
6
|
+
this.enabled = false;
|
|
7
|
+
this.clickThrottleInterval = options.clickThrottleInterval ?? 500;
|
|
8
|
+
this.scrollDebounceInterval = options.scrollDebounceInterval ?? 250;
|
|
9
|
+
this.handleClick = this.handleClick.bind(this);
|
|
10
|
+
this.handleScroll = this.handleScroll.bind(this);
|
|
11
|
+
}
|
|
12
|
+
addListener(type, listener) {
|
|
13
|
+
this.eventManager.addListener(type, listener);
|
|
14
|
+
}
|
|
15
|
+
removeListener(type, listener) {
|
|
16
|
+
this.eventManager.removeListener(type, listener);
|
|
17
|
+
}
|
|
18
|
+
isEnabled() {
|
|
19
|
+
return this.enabled;
|
|
20
|
+
}
|
|
21
|
+
enable() {
|
|
22
|
+
if (this.enabled) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
this.enabled = true;
|
|
26
|
+
window.addEventListener("click", this.handleClick, true);
|
|
27
|
+
window.addEventListener("scroll", this.handleScroll, true);
|
|
28
|
+
}
|
|
29
|
+
disable() {
|
|
30
|
+
if (!this.enabled) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
this.enabled = false;
|
|
34
|
+
window.removeEventListener("click", this.handleClick, true);
|
|
35
|
+
window.removeEventListener("scroll", this.handleScroll, true);
|
|
36
|
+
this.flushPendingScroll();
|
|
37
|
+
}
|
|
38
|
+
handleClick(event) {
|
|
39
|
+
const currentTime = Date.now();
|
|
40
|
+
if (currentTime - this.lastClickTime < this.clickThrottleInterval) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
this.lastClickTime = currentTime;
|
|
44
|
+
this.eventManager.dispatch("userClicked", {
|
|
45
|
+
type: "userClicked",
|
|
46
|
+
point: {
|
|
47
|
+
x: Math.max(0, Math.round(event.pageX)),
|
|
48
|
+
y: Math.max(0, Math.round(event.pageY))
|
|
49
|
+
},
|
|
50
|
+
surfaceSize: {
|
|
51
|
+
width: document.documentElement.scrollWidth,
|
|
52
|
+
height: document.documentElement.scrollHeight
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
handleScroll() {
|
|
57
|
+
const currentPosition = {
|
|
58
|
+
x: Math.max(0, Math.round(window.scrollX)),
|
|
59
|
+
y: Math.max(0, Math.round(window.scrollY))
|
|
60
|
+
};
|
|
61
|
+
if (this.scrollState === void 0) {
|
|
62
|
+
this.scrollState = {
|
|
63
|
+
start: currentPosition,
|
|
64
|
+
lastPosition: currentPosition
|
|
65
|
+
};
|
|
66
|
+
} else if (this.hasDirectionChanged(this.scrollState, currentPosition)) {
|
|
67
|
+
const turningPoint = this.scrollState.lastPosition;
|
|
68
|
+
this.flushPendingScroll(turningPoint);
|
|
69
|
+
this.scrollState = {
|
|
70
|
+
start: turningPoint,
|
|
71
|
+
lastPosition: currentPosition
|
|
72
|
+
};
|
|
73
|
+
} else {
|
|
74
|
+
this.scrollState.lastPosition = currentPosition;
|
|
75
|
+
}
|
|
76
|
+
if (this.scrollDebounceTimer !== void 0) {
|
|
77
|
+
window.clearTimeout(this.scrollDebounceTimer);
|
|
78
|
+
}
|
|
79
|
+
this.scrollDebounceTimer = window.setTimeout(
|
|
80
|
+
() => this.flushPendingScroll(),
|
|
81
|
+
this.scrollDebounceInterval
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Determines whether the scroll direction has reversed on either axis.
|
|
86
|
+
*
|
|
87
|
+
* It compares two vectors:
|
|
88
|
+
* - The scroll direction: the overall direction from start to the previous position (start -> previous)
|
|
89
|
+
* - The movement direction: the direction of the latest movement (previous -> current)
|
|
90
|
+
*
|
|
91
|
+
* A reversal is detected when these two vectors point in opposite directions on the same axis.
|
|
92
|
+
* Axes with no movement (sign = 0) are ignored, so scrolling that simply stops on one axis
|
|
93
|
+
* without reversing does not trigger a flush.
|
|
94
|
+
*
|
|
95
|
+
* Example of vertical reversal:
|
|
96
|
+
* start = {y: 0}, previous = {y: 500}, current = {y: 400}
|
|
97
|
+
* scrollDirectionY = sign(500 - 0) = +1 (downward)
|
|
98
|
+
* movementDirectionY = sign(400 - 500) = -1 (upward)
|
|
99
|
+
* +1 !== -1 => reversed
|
|
100
|
+
*
|
|
101
|
+
* Example of no reversal (same direction):
|
|
102
|
+
* start = {y: 0}, previous = {y: 200}, current = {y: 500}
|
|
103
|
+
* scrollDirectionY = sign(200 - 0) = +1 (downward)
|
|
104
|
+
* movementDirectionY = sign(500 - 200) = +1 (downward)
|
|
105
|
+
* +1 === +1 => not reversed
|
|
106
|
+
*
|
|
107
|
+
* Example of horizontal stop ignored:
|
|
108
|
+
* start = {x: 0}, previous = {x: 300}, current = {x: 300}
|
|
109
|
+
* scrollDirectionX = sign(300 - 0) = +1
|
|
110
|
+
* movementDirectionX = sign(300 - 300) = 0 (no movement)
|
|
111
|
+
* movementDirectionX is 0 => ignored, not a reversal
|
|
112
|
+
*/
|
|
113
|
+
hasDirectionChanged(state, current) {
|
|
114
|
+
const { start, lastPosition: previous } = state;
|
|
115
|
+
const scrollDirectionX = Math.sign(previous.x - start.x);
|
|
116
|
+
const scrollDirectionY = Math.sign(previous.y - start.y);
|
|
117
|
+
const movementDirectionX = Math.sign(current.x - previous.x);
|
|
118
|
+
const movementDirectionY = Math.sign(current.y - previous.y);
|
|
119
|
+
return scrollDirectionX !== 0 && movementDirectionX !== 0 && scrollDirectionX !== movementDirectionX || scrollDirectionY !== 0 && movementDirectionY !== 0 && scrollDirectionY !== movementDirectionY;
|
|
120
|
+
}
|
|
121
|
+
flushPendingScroll(end) {
|
|
122
|
+
if (this.scrollDebounceTimer !== void 0) {
|
|
123
|
+
window.clearTimeout(this.scrollDebounceTimer);
|
|
124
|
+
this.scrollDebounceTimer = void 0;
|
|
125
|
+
}
|
|
126
|
+
if (this.scrollState === void 0) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const { start } = this.scrollState;
|
|
130
|
+
const destination = end ?? {
|
|
131
|
+
x: Math.max(0, Math.round(window.scrollX)),
|
|
132
|
+
y: Math.max(0, Math.round(window.scrollY))
|
|
133
|
+
};
|
|
134
|
+
this.scrollState = void 0;
|
|
135
|
+
if (start.x === destination.x && start.y === destination.y) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
this.eventManager.dispatch("userScrolled", {
|
|
139
|
+
type: "userScrolled",
|
|
140
|
+
start,
|
|
141
|
+
end: destination,
|
|
142
|
+
surfaceSize: {
|
|
143
|
+
width: document.documentElement.scrollWidth,
|
|
144
|
+
height: document.documentElement.scrollHeight
|
|
145
|
+
},
|
|
146
|
+
// Uses clientWidth/clientHeight instead of innerWidth/innerHeight to get the
|
|
147
|
+
// layout viewport size, which remains stable regardless of pinch-to-zoom level
|
|
148
|
+
// on mobile devices.
|
|
149
|
+
viewportSize: {
|
|
150
|
+
width: document.documentElement.clientWidth,
|
|
151
|
+
height: document.documentElement.clientHeight
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export {
|
|
157
|
+
InteractionMonitor
|
|
158
|
+
};
|
package/package.json
CHANGED
package/schema/eventSchemas.cjs
CHANGED
|
@@ -28,6 +28,8 @@ __export(eventSchemas_exports, {
|
|
|
28
28
|
orderPlaced: () => orderPlaced,
|
|
29
29
|
postViewed: () => postViewed,
|
|
30
30
|
productViewed: () => productViewed,
|
|
31
|
+
userClicked: () => userClicked,
|
|
32
|
+
userScrolled: () => userScrolled,
|
|
31
33
|
userSignedUp: () => userSignedUp
|
|
32
34
|
});
|
|
33
35
|
module.exports = __toCommonJS(eventSchemas_exports);
|
|
@@ -146,6 +148,48 @@ const eventOccurred = new import_validation.ObjectType({
|
|
|
146
148
|
})
|
|
147
149
|
}
|
|
148
150
|
});
|
|
151
|
+
const point = new import_validation.ObjectType({
|
|
152
|
+
required: ["x", "y"],
|
|
153
|
+
properties: {
|
|
154
|
+
x: new import_validation.NumberType({
|
|
155
|
+
integer: true,
|
|
156
|
+
minimum: 0
|
|
157
|
+
}),
|
|
158
|
+
y: new import_validation.NumberType({
|
|
159
|
+
integer: true,
|
|
160
|
+
minimum: 0
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
const size = new import_validation.ObjectType({
|
|
165
|
+
required: ["width", "height"],
|
|
166
|
+
properties: {
|
|
167
|
+
width: new import_validation.NumberType({
|
|
168
|
+
integer: true,
|
|
169
|
+
minimum: 0
|
|
170
|
+
}),
|
|
171
|
+
height: new import_validation.NumberType({
|
|
172
|
+
integer: true,
|
|
173
|
+
minimum: 0
|
|
174
|
+
})
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
const userClicked = new import_validation.ObjectType({
|
|
178
|
+
required: ["point"],
|
|
179
|
+
properties: {
|
|
180
|
+
point,
|
|
181
|
+
surfaceSize: size
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
const userScrolled = new import_validation.ObjectType({
|
|
185
|
+
required: ["end"],
|
|
186
|
+
properties: {
|
|
187
|
+
start: point,
|
|
188
|
+
end: point,
|
|
189
|
+
surfaceSize: size,
|
|
190
|
+
viewportSize: size
|
|
191
|
+
}
|
|
192
|
+
});
|
|
149
193
|
const leadGenerated = new import_validation.ObjectType({
|
|
150
194
|
properties: {
|
|
151
195
|
leadId: new import_validation.StringType({
|
|
@@ -175,5 +219,7 @@ const leadGenerated = new import_validation.ObjectType({
|
|
|
175
219
|
orderPlaced,
|
|
176
220
|
postViewed,
|
|
177
221
|
productViewed,
|
|
222
|
+
userClicked,
|
|
223
|
+
userScrolled,
|
|
178
224
|
userSignedUp
|
|
179
225
|
});
|
|
@@ -12,6 +12,8 @@ declare const interestShown: ObjectType;
|
|
|
12
12
|
declare const postViewed: ObjectType;
|
|
13
13
|
declare const linkOpened: ObjectType;
|
|
14
14
|
declare const eventOccurred: ObjectType;
|
|
15
|
+
declare const userClicked: ObjectType;
|
|
16
|
+
declare const userScrolled: ObjectType;
|
|
15
17
|
declare const leadGenerated: ObjectType;
|
|
16
18
|
|
|
17
|
-
export { cartModified, cartViewed, checkoutStarted, eventOccurred, goalCompleted, interestShown, leadGenerated, linkOpened, orderPlaced, postViewed, productViewed, userSignedUp };
|
|
19
|
+
export { cartModified, cartViewed, checkoutStarted, eventOccurred, goalCompleted, interestShown, leadGenerated, linkOpened, orderPlaced, postViewed, productViewed, userClicked, userScrolled, userSignedUp };
|
package/schema/eventSchemas.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ declare const interestShown: ObjectType;
|
|
|
12
12
|
declare const postViewed: ObjectType;
|
|
13
13
|
declare const linkOpened: ObjectType;
|
|
14
14
|
declare const eventOccurred: ObjectType;
|
|
15
|
+
declare const userClicked: ObjectType;
|
|
16
|
+
declare const userScrolled: ObjectType;
|
|
15
17
|
declare const leadGenerated: ObjectType;
|
|
16
18
|
|
|
17
|
-
export { cartModified, cartViewed, checkoutStarted, eventOccurred, goalCompleted, interestShown, leadGenerated, linkOpened, orderPlaced, postViewed, productViewed, userSignedUp };
|
|
19
|
+
export { cartModified, cartViewed, checkoutStarted, eventOccurred, goalCompleted, interestShown, leadGenerated, linkOpened, orderPlaced, postViewed, productViewed, userClicked, userScrolled, userSignedUp };
|
package/schema/eventSchemas.js
CHANGED
|
@@ -121,6 +121,48 @@ const eventOccurred = new ObjectType({
|
|
|
121
121
|
})
|
|
122
122
|
}
|
|
123
123
|
});
|
|
124
|
+
const point = new ObjectType({
|
|
125
|
+
required: ["x", "y"],
|
|
126
|
+
properties: {
|
|
127
|
+
x: new NumberType({
|
|
128
|
+
integer: true,
|
|
129
|
+
minimum: 0
|
|
130
|
+
}),
|
|
131
|
+
y: new NumberType({
|
|
132
|
+
integer: true,
|
|
133
|
+
minimum: 0
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
const size = new ObjectType({
|
|
138
|
+
required: ["width", "height"],
|
|
139
|
+
properties: {
|
|
140
|
+
width: new NumberType({
|
|
141
|
+
integer: true,
|
|
142
|
+
minimum: 0
|
|
143
|
+
}),
|
|
144
|
+
height: new NumberType({
|
|
145
|
+
integer: true,
|
|
146
|
+
minimum: 0
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
const userClicked = new ObjectType({
|
|
151
|
+
required: ["point"],
|
|
152
|
+
properties: {
|
|
153
|
+
point,
|
|
154
|
+
surfaceSize: size
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
const userScrolled = new ObjectType({
|
|
158
|
+
required: ["end"],
|
|
159
|
+
properties: {
|
|
160
|
+
start: point,
|
|
161
|
+
end: point,
|
|
162
|
+
surfaceSize: size,
|
|
163
|
+
viewportSize: size
|
|
164
|
+
}
|
|
165
|
+
});
|
|
124
166
|
const leadGenerated = new ObjectType({
|
|
125
167
|
properties: {
|
|
126
168
|
leadId: new StringType({
|
|
@@ -149,5 +191,7 @@ export {
|
|
|
149
191
|
orderPlaced,
|
|
150
192
|
postViewed,
|
|
151
193
|
productViewed,
|
|
194
|
+
userClicked,
|
|
195
|
+
userScrolled,
|
|
152
196
|
userSignedUp
|
|
153
197
|
};
|
package/schema/index.d.cts
CHANGED
|
@@ -2,7 +2,7 @@ export { tokenScopeSchema } from './contextSchemas.cjs';
|
|
|
2
2
|
export { cart, cartItem, order, orderItem, productDetails } from './ecommerceSchemas.cjs';
|
|
3
3
|
export { evaluationOptionsSchema } from './evaluatorSchemas.cjs';
|
|
4
4
|
export { fetchOptionsSchema } from './contentFetcherSchemas.cjs';
|
|
5
|
-
export { cartModified, cartViewed, checkoutStarted, eventOccurred, goalCompleted, interestShown, leadGenerated, linkOpened, orderPlaced, postViewed, productViewed, userSignedUp } from './eventSchemas.cjs';
|
|
5
|
+
export { cartModified, cartViewed, checkoutStarted, eventOccurred, goalCompleted, interestShown, leadGenerated, linkOpened, orderPlaced, postViewed, productViewed, userClicked, userScrolled, userSignedUp } from './eventSchemas.cjs';
|
|
6
6
|
export { loggerSchema } from './loggerSchema.cjs';
|
|
7
7
|
export { addOperation, clearOperation, combineOperation, decrementOperation, incrementOperation, mergeOperation, removeOperation, setOperation, unsetOperation } from './operationSchemas.cjs';
|
|
8
8
|
export { sdkFacadeConfigurationSchema } from './sdkFacadeSchemas.cjs';
|
package/schema/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { tokenScopeSchema } from './contextSchemas.js';
|
|
|
2
2
|
export { cart, cartItem, order, orderItem, productDetails } from './ecommerceSchemas.js';
|
|
3
3
|
export { evaluationOptionsSchema } from './evaluatorSchemas.js';
|
|
4
4
|
export { fetchOptionsSchema } from './contentFetcherSchemas.js';
|
|
5
|
-
export { cartModified, cartViewed, checkoutStarted, eventOccurred, goalCompleted, interestShown, leadGenerated, linkOpened, orderPlaced, postViewed, productViewed, userSignedUp } from './eventSchemas.js';
|
|
5
|
+
export { cartModified, cartViewed, checkoutStarted, eventOccurred, goalCompleted, interestShown, leadGenerated, linkOpened, orderPlaced, postViewed, productViewed, userClicked, userScrolled, userSignedUp } from './eventSchemas.js';
|
|
6
6
|
export { loggerSchema } from './loggerSchema.js';
|
|
7
7
|
export { addOperation, clearOperation, combineOperation, decrementOperation, incrementOperation, mergeOperation, removeOperation, setOperation, unsetOperation } from './operationSchemas.js';
|
|
8
8
|
export { sdkFacadeConfigurationSchema } from './sdkFacadeSchemas.js';
|
package/sdk.cjs
CHANGED
package/sdk.d.cts
CHANGED
|
@@ -49,6 +49,7 @@ declare class Sdk {
|
|
|
49
49
|
private constructor();
|
|
50
50
|
static init(configuration: Configuration): Sdk;
|
|
51
51
|
get appId(): string;
|
|
52
|
+
get timeZone(): string | null;
|
|
52
53
|
get cidAssigner(): CidAssigner;
|
|
53
54
|
get previewTokenStore(): TokenStore;
|
|
54
55
|
get userTokenStore(): TokenStore;
|
package/sdk.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ declare class Sdk {
|
|
|
49
49
|
private constructor();
|
|
50
50
|
static init(configuration: Configuration): Sdk;
|
|
51
51
|
get appId(): string;
|
|
52
|
+
get timeZone(): string | null;
|
|
52
53
|
get cidAssigner(): CidAssigner;
|
|
53
54
|
get previewTokenStore(): TokenStore;
|
|
54
55
|
get userTokenStore(): TokenStore;
|
package/sdk.js
CHANGED
package/tracker.cjs
CHANGED
|
@@ -21,6 +21,7 @@ __export(tracker_exports, {
|
|
|
21
21
|
});
|
|
22
22
|
module.exports = __toCommonJS(tracker_exports);
|
|
23
23
|
var import_logging = require('./logging/index.cjs');
|
|
24
|
+
var import_interactionMonitor = require('./interactionMonitor.cjs');
|
|
24
25
|
var import_error = require('./error.cjs');
|
|
25
26
|
var import_trackingEvents = require('./trackingEvents.cjs');
|
|
26
27
|
const trackedEvents = {};
|
|
@@ -36,16 +37,20 @@ class Tracker {
|
|
|
36
37
|
this.inactivityTimer = {
|
|
37
38
|
since: 0
|
|
38
39
|
};
|
|
39
|
-
const { tab, tokenProvider, channel, logger, inactivityRetryPolicy, ...options } = config;
|
|
40
|
+
const { tab, tokenProvider, channel, logger, inactivityRetryPolicy, timeZone, ...options } = config;
|
|
40
41
|
this.tab = tab;
|
|
41
42
|
this.tokenProvider = tokenProvider;
|
|
42
43
|
this.inactivityRetryPolicy = inactivityRetryPolicy;
|
|
43
44
|
this.channel = channel;
|
|
45
|
+
this.timeZone = timeZone;
|
|
44
46
|
this.logger = logger ?? new import_logging.NullLogger();
|
|
45
47
|
this.options = {
|
|
46
48
|
...options,
|
|
47
49
|
eventMetadata: options.eventMetadata ?? {}
|
|
48
50
|
};
|
|
51
|
+
this.interactionMonitor = new import_interactionMonitor.InteractionMonitor();
|
|
52
|
+
this.interactionMonitor.addListener("userClicked", (event) => this.enqueue(event));
|
|
53
|
+
this.interactionMonitor.addListener("userScrolled", (event) => this.enqueue(event));
|
|
49
54
|
this.enable = this.enable.bind(this);
|
|
50
55
|
this.disable = this.disable.bind(this);
|
|
51
56
|
this.suspend = this.suspend.bind(this);
|
|
@@ -93,6 +98,7 @@ class Tracker {
|
|
|
93
98
|
this.tab.addListener("load", this.trackPageLoad);
|
|
94
99
|
this.tab.addListener("urlChange", this.trackTabUrlChange);
|
|
95
100
|
this.tab.addListener("visibilityChange", this.trackTabVisibilityChange);
|
|
101
|
+
this.interactionMonitor.enable();
|
|
96
102
|
}
|
|
97
103
|
disable() {
|
|
98
104
|
if (!this.state.enabled) {
|
|
@@ -103,6 +109,7 @@ class Tracker {
|
|
|
103
109
|
if (this.state.suspended) {
|
|
104
110
|
return;
|
|
105
111
|
}
|
|
112
|
+
this.interactionMonitor.disable();
|
|
106
113
|
this.tab.removeListener("load", this.trackPageLoad);
|
|
107
114
|
this.tab.removeListener("urlChange", this.trackTabUrlChange);
|
|
108
115
|
this.tab.removeListener("visibilityChange", this.trackTabVisibilityChange);
|
|
@@ -231,6 +238,7 @@ class Tracker {
|
|
|
231
238
|
const context = {
|
|
232
239
|
tabId: this.tab.id,
|
|
233
240
|
url: this.tab.url,
|
|
241
|
+
...this.timeZone !== void 0 ? { timeZone: this.timeZone } : {},
|
|
234
242
|
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
235
243
|
};
|
|
236
244
|
return this.publish({
|
package/tracker.d.cts
CHANGED
|
@@ -23,6 +23,7 @@ type Configuration = Options & {
|
|
|
23
23
|
channel: OutputChannel<Beacon>;
|
|
24
24
|
logger?: Logger;
|
|
25
25
|
tab: Tab;
|
|
26
|
+
timeZone?: string;
|
|
26
27
|
tokenProvider: TokenProvider;
|
|
27
28
|
inactivityRetryPolicy: RetryPolicy<number>;
|
|
28
29
|
};
|
|
@@ -42,11 +43,13 @@ declare class Tracker {
|
|
|
42
43
|
private tab;
|
|
43
44
|
private tokenProvider;
|
|
44
45
|
private inactivityRetryPolicy;
|
|
46
|
+
private readonly timeZone?;
|
|
45
47
|
private readonly channel;
|
|
46
48
|
private readonly logger;
|
|
47
49
|
private readonly listeners;
|
|
48
50
|
private readonly pending;
|
|
49
51
|
private readonly state;
|
|
52
|
+
private readonly interactionMonitor;
|
|
50
53
|
private readonly inactivityTimer;
|
|
51
54
|
constructor(config: Configuration);
|
|
52
55
|
addListener(listener: EventListener): void;
|
package/tracker.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ type Configuration = Options & {
|
|
|
23
23
|
channel: OutputChannel<Beacon>;
|
|
24
24
|
logger?: Logger;
|
|
25
25
|
tab: Tab;
|
|
26
|
+
timeZone?: string;
|
|
26
27
|
tokenProvider: TokenProvider;
|
|
27
28
|
inactivityRetryPolicy: RetryPolicy<number>;
|
|
28
29
|
};
|
|
@@ -42,11 +43,13 @@ declare class Tracker {
|
|
|
42
43
|
private tab;
|
|
43
44
|
private tokenProvider;
|
|
44
45
|
private inactivityRetryPolicy;
|
|
46
|
+
private readonly timeZone?;
|
|
45
47
|
private readonly channel;
|
|
46
48
|
private readonly logger;
|
|
47
49
|
private readonly listeners;
|
|
48
50
|
private readonly pending;
|
|
49
51
|
private readonly state;
|
|
52
|
+
private readonly interactionMonitor;
|
|
50
53
|
private readonly inactivityTimer;
|
|
51
54
|
constructor(config: Configuration);
|
|
52
55
|
addListener(listener: EventListener): void;
|
package/tracker.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NullLogger } from "./logging/index.js";
|
|
2
|
+
import { InteractionMonitor } from "./interactionMonitor.js";
|
|
2
3
|
import { formatCause } from "./error.js";
|
|
3
4
|
import { isCartPartialEvent, isIdentifiedUserEvent } from "./trackingEvents.js";
|
|
4
5
|
const trackedEvents = {};
|
|
@@ -14,16 +15,20 @@ class Tracker {
|
|
|
14
15
|
this.inactivityTimer = {
|
|
15
16
|
since: 0
|
|
16
17
|
};
|
|
17
|
-
const { tab, tokenProvider, channel, logger, inactivityRetryPolicy, ...options } = config;
|
|
18
|
+
const { tab, tokenProvider, channel, logger, inactivityRetryPolicy, timeZone, ...options } = config;
|
|
18
19
|
this.tab = tab;
|
|
19
20
|
this.tokenProvider = tokenProvider;
|
|
20
21
|
this.inactivityRetryPolicy = inactivityRetryPolicy;
|
|
21
22
|
this.channel = channel;
|
|
23
|
+
this.timeZone = timeZone;
|
|
22
24
|
this.logger = logger ?? new NullLogger();
|
|
23
25
|
this.options = {
|
|
24
26
|
...options,
|
|
25
27
|
eventMetadata: options.eventMetadata ?? {}
|
|
26
28
|
};
|
|
29
|
+
this.interactionMonitor = new InteractionMonitor();
|
|
30
|
+
this.interactionMonitor.addListener("userClicked", (event) => this.enqueue(event));
|
|
31
|
+
this.interactionMonitor.addListener("userScrolled", (event) => this.enqueue(event));
|
|
27
32
|
this.enable = this.enable.bind(this);
|
|
28
33
|
this.disable = this.disable.bind(this);
|
|
29
34
|
this.suspend = this.suspend.bind(this);
|
|
@@ -71,6 +76,7 @@ class Tracker {
|
|
|
71
76
|
this.tab.addListener("load", this.trackPageLoad);
|
|
72
77
|
this.tab.addListener("urlChange", this.trackTabUrlChange);
|
|
73
78
|
this.tab.addListener("visibilityChange", this.trackTabVisibilityChange);
|
|
79
|
+
this.interactionMonitor.enable();
|
|
74
80
|
}
|
|
75
81
|
disable() {
|
|
76
82
|
if (!this.state.enabled) {
|
|
@@ -81,6 +87,7 @@ class Tracker {
|
|
|
81
87
|
if (this.state.suspended) {
|
|
82
88
|
return;
|
|
83
89
|
}
|
|
90
|
+
this.interactionMonitor.disable();
|
|
84
91
|
this.tab.removeListener("load", this.trackPageLoad);
|
|
85
92
|
this.tab.removeListener("urlChange", this.trackTabUrlChange);
|
|
86
93
|
this.tab.removeListener("visibilityChange", this.trackTabVisibilityChange);
|
|
@@ -209,6 +216,7 @@ class Tracker {
|
|
|
209
216
|
const context = {
|
|
210
217
|
tabId: this.tab.id,
|
|
211
218
|
url: this.tab.url,
|
|
219
|
+
...this.timeZone !== void 0 ? { timeZone: this.timeZone } : {},
|
|
212
220
|
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
213
221
|
};
|
|
214
222
|
return this.publish({
|
package/trackingEvents.cjs
CHANGED
|
@@ -21,6 +21,7 @@ __export(trackingEvents_exports, {
|
|
|
21
21
|
ecommerceEventTypes: () => ecommerceEventTypes,
|
|
22
22
|
eventTypes: () => eventTypes,
|
|
23
23
|
identifiedUserEventTypes: () => identifiedUserEventTypes,
|
|
24
|
+
interactionEventTypes: () => interactionEventTypes,
|
|
24
25
|
isCartPartialEvent: () => isCartPartialEvent,
|
|
25
26
|
isIdentifiedUserEvent: () => isIdentifiedUserEvent,
|
|
26
27
|
miscEventTypes: () => miscEventTypes,
|
|
@@ -57,6 +58,10 @@ const userEventTypes = [
|
|
|
57
58
|
...identifiedUserEventTypes,
|
|
58
59
|
"userProfileChanged"
|
|
59
60
|
];
|
|
61
|
+
const interactionEventTypes = [
|
|
62
|
+
"userClicked",
|
|
63
|
+
"userScrolled"
|
|
64
|
+
];
|
|
60
65
|
const miscEventTypes = [
|
|
61
66
|
"nothingChanged",
|
|
62
67
|
"sessionAttributesChanged",
|
|
@@ -71,6 +76,7 @@ const eventTypes = [
|
|
|
71
76
|
...pageEventTypes,
|
|
72
77
|
...ecommerceEventTypes,
|
|
73
78
|
...userEventTypes,
|
|
79
|
+
...interactionEventTypes,
|
|
74
80
|
...miscEventTypes
|
|
75
81
|
];
|
|
76
82
|
function isIdentifiedUserEvent(event) {
|
|
@@ -85,6 +91,7 @@ function isCartPartialEvent(event) {
|
|
|
85
91
|
ecommerceEventTypes,
|
|
86
92
|
eventTypes,
|
|
87
93
|
identifiedUserEventTypes,
|
|
94
|
+
interactionEventTypes,
|
|
88
95
|
isCartPartialEvent,
|
|
89
96
|
isIdentifiedUserEvent,
|
|
90
97
|
miscEventTypes,
|
package/trackingEvents.d.cts
CHANGED
|
@@ -67,6 +67,14 @@ type Order = {
|
|
|
67
67
|
installments?: number;
|
|
68
68
|
status?: OrderStatus;
|
|
69
69
|
};
|
|
70
|
+
type Point = {
|
|
71
|
+
x: number;
|
|
72
|
+
y: number;
|
|
73
|
+
};
|
|
74
|
+
type Size = {
|
|
75
|
+
width: number;
|
|
76
|
+
height: number;
|
|
77
|
+
};
|
|
70
78
|
type Gender = 'male' | 'female' | 'neutral' | 'unknown';
|
|
71
79
|
declare const pageEventTypes: readonly ["pageLoaded", "pageOpened"];
|
|
72
80
|
declare const tabEventTypes: readonly ["tabOpened", "tabUrlChanged", "tabVisibilityChanged"];
|
|
@@ -74,8 +82,9 @@ declare const cartEventTypes: readonly ["cartModified", "cartViewed", "checkoutS
|
|
|
74
82
|
declare const ecommerceEventTypes: readonly ["cartModified", "cartViewed", "checkoutStarted", "orderPlaced", "productViewed"];
|
|
75
83
|
declare const identifiedUserEventTypes: string[];
|
|
76
84
|
declare const userEventTypes: readonly [...string[], "userProfileChanged"];
|
|
85
|
+
declare const interactionEventTypes: readonly ["userClicked", "userScrolled"];
|
|
77
86
|
declare const miscEventTypes: readonly ["nothingChanged", "sessionAttributesChanged", "goalCompleted", "interestShown", "postViewed", "eventOccurred", "linkOpened", "leadGenerated"];
|
|
78
|
-
declare const eventTypes: readonly ["pageLoaded", "pageOpened", "cartModified", "cartViewed", "checkoutStarted", "orderPlaced", "productViewed", ...string[], "userProfileChanged", "nothingChanged", "sessionAttributesChanged", "goalCompleted", "interestShown", "postViewed", "eventOccurred", "linkOpened", "leadGenerated"];
|
|
87
|
+
declare const eventTypes: readonly ["pageLoaded", "pageOpened", "cartModified", "cartViewed", "checkoutStarted", "orderPlaced", "productViewed", ...string[], "userProfileChanged", "userClicked", "userScrolled", "nothingChanged", "sessionAttributesChanged", "goalCompleted", "interestShown", "postViewed", "eventOccurred", "linkOpened", "leadGenerated"];
|
|
79
88
|
interface BaseEvent {
|
|
80
89
|
type: string;
|
|
81
90
|
}
|
|
@@ -195,6 +204,19 @@ interface PageLoaded extends BasePageEvent {
|
|
|
195
204
|
lastModifiedTime: number;
|
|
196
205
|
}
|
|
197
206
|
type PageEvent = PageLoaded | PageOpened;
|
|
207
|
+
interface UserClicked extends BaseEvent {
|
|
208
|
+
type: 'userClicked';
|
|
209
|
+
point: Point;
|
|
210
|
+
surfaceSize?: Size;
|
|
211
|
+
}
|
|
212
|
+
interface UserScrolled extends BaseEvent {
|
|
213
|
+
type: 'userScrolled';
|
|
214
|
+
start?: Point;
|
|
215
|
+
end: Point;
|
|
216
|
+
surfaceSize?: Size;
|
|
217
|
+
viewportSize?: Size;
|
|
218
|
+
}
|
|
219
|
+
type InteractionEvent = UserClicked | UserScrolled;
|
|
198
220
|
interface NothingChanged extends BaseEvent {
|
|
199
221
|
type: 'nothingChanged';
|
|
200
222
|
sinceTime: number;
|
|
@@ -256,6 +278,8 @@ type EventMap = {
|
|
|
256
278
|
userSignedOut: UserSignedOut;
|
|
257
279
|
userSignedUp: UserSignedUp;
|
|
258
280
|
userProfileChanged: UserProfileChanged;
|
|
281
|
+
userClicked: UserClicked;
|
|
282
|
+
userScrolled: UserScrolled;
|
|
259
283
|
productViewed: ProductViewed;
|
|
260
284
|
cartViewed: CartViewed;
|
|
261
285
|
cartModified: CartModified;
|
|
@@ -302,6 +326,7 @@ declare function isCartPartialEvent(event: PartialTrackingEvent): event is CartP
|
|
|
302
326
|
type TrackingEventContext = {
|
|
303
327
|
tabId: string;
|
|
304
328
|
url: string;
|
|
329
|
+
timeZone?: string;
|
|
305
330
|
metadata?: {
|
|
306
331
|
[key: string]: string;
|
|
307
332
|
};
|
|
@@ -318,4 +343,4 @@ type Beacon = {
|
|
|
318
343
|
payload: BeaconPayload;
|
|
319
344
|
};
|
|
320
345
|
|
|
321
|
-
export { type Beacon, type BeaconPayload, type Cart, type CartEvent, type CartEventType, type CartItem, type CartModified, type CartViewed, type CheckoutStarted, type EcommerceEvent, type EventOccurred, type ExternalTrackingEvent, type ExternalTrackingEventPayload, type ExternalTrackingEventType, type Gender, type GoalCompleted, type IdentifiedUserEvent, type InterestShown, type LeadGenerated, type LinkOpened, type MiscEvent, type NothingChanged, type Order, type OrderItem, type OrderPlaced, type OrderStatus, type PageEvent, type PageEventType, type PageLoaded, type PageOpened, type PartialTrackingEvent, type PostDetails, type PostViewed, type ProductDetails, type ProductViewed, type SessionAttributesChanged, type TabEvent, type TabEventType, type TabOpened, type TabUrlChanged, type TabVisibilityChanged, type TrackingEvent, type TrackingEventContext, type TrackingEventType, type UserEvent, type UserProfile, type UserProfileChanged, type UserSignedIn, type UserSignedOut, type UserSignedUp, cartEventTypes, ecommerceEventTypes, eventTypes, identifiedUserEventTypes, isCartPartialEvent, isIdentifiedUserEvent, miscEventTypes, pageEventTypes, tabEventTypes, userEventTypes };
|
|
346
|
+
export { type Beacon, type BeaconPayload, type Cart, type CartEvent, type CartEventType, type CartItem, type CartModified, type CartViewed, type CheckoutStarted, type EcommerceEvent, type EventOccurred, type ExternalTrackingEvent, type ExternalTrackingEventPayload, type ExternalTrackingEventType, type Gender, type GoalCompleted, type IdentifiedUserEvent, type InteractionEvent, type InterestShown, type LeadGenerated, type LinkOpened, type MiscEvent, type NothingChanged, type Order, type OrderItem, type OrderPlaced, type OrderStatus, type PageEvent, type PageEventType, type PageLoaded, type PageOpened, type PartialTrackingEvent, type Point, type PostDetails, type PostViewed, type ProductDetails, type ProductViewed, type SessionAttributesChanged, type Size, type TabEvent, type TabEventType, type TabOpened, type TabUrlChanged, type TabVisibilityChanged, type TrackingEvent, type TrackingEventContext, type TrackingEventType, type UserClicked, type UserEvent, type UserProfile, type UserProfileChanged, type UserScrolled, type UserSignedIn, type UserSignedOut, type UserSignedUp, cartEventTypes, ecommerceEventTypes, eventTypes, identifiedUserEventTypes, interactionEventTypes, isCartPartialEvent, isIdentifiedUserEvent, miscEventTypes, pageEventTypes, tabEventTypes, userEventTypes };
|