@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.
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@croct/sdk",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Croct SDK for JavaScript.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -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 };
@@ -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 };
@@ -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
  };
@@ -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
@@ -83,6 +83,9 @@ class Sdk {
83
83
  const { appId } = this.container.getConfiguration();
84
84
  return appId;
85
85
  }
86
+ get timeZone() {
87
+ return this.container.getTimeZone();
88
+ }
86
89
  get cidAssigner() {
87
90
  return this.container.getCidAssigner();
88
91
  }
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
@@ -61,6 +61,9 @@ class Sdk {
61
61
  const { appId } = this.container.getConfiguration();
62
62
  return appId;
63
63
  }
64
+ get timeZone() {
65
+ return this.container.getTimeZone();
66
+ }
64
67
  get cidAssigner() {
65
68
  return this.container.getCidAssigner();
66
69
  }
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({
@@ -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,
@@ -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 };