@gemx-dev/clarity-js 0.8.46 → 0.8.48

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.
@@ -1,25 +1,24 @@
1
- import { Time } from "@clarity-types/core";
2
- import { BooleanFlag, Constant, Dimension, Metadata, MetadataCallback, MetadataCallbackOptions, Metric, Session, User, Setting, ConsentState, ConsentSource, ConsentData } from "@clarity-types/data";
1
+ import { Constant as CoreConstant, Time } from "@clarity-types/core";
2
+ import { BooleanFlag, ConsentData, ConsentSource, ConsentState, Constant, Dimension, Metadata, MetadataCallback, MetadataCallbackOptions, Metric, Session, Setting, User } from "@clarity-types/data";
3
3
  import * as clarity from "@src/clarity";
4
4
  import * as core from "@src/core";
5
5
  import config from "@src/core/config";
6
6
  import hash from "@src/core/hash";
7
7
  import * as scrub from "@src/core/scrub";
8
+ import * as trackConsent from "@src/data/consent";
9
+ import { COOKIE_SEP, getCookie, setCookie } from "@src/data/cookie";
8
10
  import * as dimension from "@src/data/dimension";
9
11
  import * as metric from "@src/data/metric";
12
+ import { supported } from "@src/data/util";
10
13
  import { set } from "@src/data/variable";
11
- import * as trackConsent from "@src/data/consent";
12
- import { Constant as CoreConstant } from "@clarity-types/core";
13
14
 
14
15
  export let data: Metadata = null;
15
16
  export let callbacks: MetadataCallbackOptions[] = [];
16
17
  export let electron = BooleanFlag.False;
17
- let rootDomain = null;
18
18
  let consentStatus: ConsentState = null;
19
- let defaultStatus: ConsentState = { source: ConsentSource.API, ad_Storage: Constant.Denied, analytics_Storage: Constant.Denied };
19
+ let defaultStatus: ConsentState = { source: ConsentSource.Default, ad_Storage: Constant.Denied, analytics_Storage: Constant.Denied };
20
20
 
21
21
  export function start(): void {
22
- rootDomain = null;
23
22
  const ua = navigator && "userAgent" in navigator ? navigator.userAgent : Constant.Empty;
24
23
  const timezone = (typeof Intl !== 'undefined' && Intl?.DateTimeFormat()?.resolvedOptions()?.timeZone) ?? '';
25
24
  const timezoneOffset = new Date().getTimezoneOffset().toString();
@@ -89,7 +88,7 @@ export function start(): void {
89
88
  // If consent status is not already set, initialize it based on project configuration. Otherwise, use the existing consent status.
90
89
  if (consentStatus === null) {
91
90
  consentStatus = {
92
- source: ConsentSource.Implicit,
91
+ source: u.consent ? ConsentSource.Cookie : ConsentSource.Implicit,
93
92
  ad_Storage: config.track ? Constant.Granted : Constant.Denied,
94
93
  analytics_Storage: config.track ? Constant.Granted : Constant.Denied,
95
94
  };
@@ -114,7 +113,6 @@ function userAgentData(): void {
114
113
  }
115
114
 
116
115
  export function stop(): void {
117
- rootDomain = null;
118
116
  data = null;
119
117
  callbacks.forEach(cb => { cb.called = false; });
120
118
  }
@@ -142,15 +140,15 @@ export function id(): string {
142
140
  //TODO: Remove this function once consentv2 is fully released
143
141
  export function consent(status = true): void {
144
142
  if (!status) {
145
- consentv2();
143
+ consentv2({ source: ConsentSource.APIv1, ad_Storage: Constant.Denied, analytics_Storage: Constant.Denied });
146
144
  return;
147
145
  }
148
146
 
149
- consentv2({ ad_Storage: Constant.Granted, analytics_Storage: Constant.Granted });
147
+ consentv2({ source: ConsentSource.APIv1, ad_Storage: Constant.Granted, analytics_Storage: Constant.Granted });
150
148
  trackConsent.consent();
151
149
  }
152
150
 
153
- export function consentv2(consentState: ConsentState = defaultStatus, source: number = ConsentSource.API): void {
151
+ export function consentv2(consentState: ConsentState = defaultStatus, source: number = ConsentSource.APIv2): void {
154
152
  const updatedStatus = {
155
153
  source: consentState.source ?? source,
156
154
  ad_Storage: normalizeConsent(consentState.ad_Storage, consentStatus?.ad_Storage),
@@ -162,6 +160,9 @@ export function consentv2(consentState: ConsentState = defaultStatus, source: nu
162
160
  updatedStatus.ad_Storage === consentStatus.ad_Storage &&
163
161
  updatedStatus.analytics_Storage === consentStatus.analytics_Storage
164
162
  ) {
163
+ consentStatus.source = updatedStatus.source;
164
+ trackConsent.trackConsentv2(getConsentData(consentStatus));
165
+ trackConsent.consent();
165
166
  return;
166
167
  }
167
168
 
@@ -171,8 +172,7 @@ export function consentv2(consentState: ConsentState = defaultStatus, source: nu
171
172
 
172
173
  if (!consentData.analytics_Storage && config.track) {
173
174
  config.track = false;
174
- setCookie(Constant.SessionKey, Constant.Empty, -Number.MAX_VALUE);
175
- setCookie(Constant.CookieKey, Constant.Empty, -Number.MAX_VALUE);
175
+ clear(true);
176
176
  clarity.stop();
177
177
  window.setTimeout(clarity.start, Setting.RestartDelay);
178
178
  return;
@@ -202,9 +202,14 @@ function normalizeConsent(value: unknown, fallback: string = Constant.Denied): s
202
202
  return typeof value === 'string' ? value.toLowerCase() : fallback;
203
203
  }
204
204
 
205
- export function clear(): void {
205
+ export function clear(all: boolean = false): void {
206
206
  // Clear any stored information in the cookie that tracks session information so we can restart fresh the next time
207
- setCookie(Constant.SessionKey, Constant.Empty, 0);
207
+ setCookie(Constant.SessionKey, Constant.Empty, -Number.MAX_VALUE);
208
+
209
+ // Clear user cookie as well if all flag is set
210
+ if (all) {
211
+ setCookie(Constant.CookieKey, Constant.Empty, -Number.MAX_VALUE);
212
+ }
208
213
  }
209
214
 
210
215
  function tab(): string {
@@ -227,7 +232,7 @@ export function save(): void {
227
232
  let ts = Math.round(Date.now());
228
233
  let upload = config.upload && typeof config.upload === Constant.String ? (config.upload as string).replace(Constant.HTTPS, Constant.Empty) : Constant.Empty;
229
234
  let upgrade = config.lean ? BooleanFlag.False : BooleanFlag.True;
230
- setCookie(Constant.SessionKey, [data.sessionId, ts, data.pageNum, upgrade, upload].join(Constant.Caret), Setting.SessionExpire);
235
+ setCookie(Constant.SessionKey, [data.sessionId, ts, data.pageNum, upgrade, upload].join(COOKIE_SEP), Setting.SessionExpire);
231
236
  }
232
237
 
233
238
  function processCallback(upgrade: BooleanFlag, consentUpdate: boolean = false): void {
@@ -250,10 +255,6 @@ function processCallback(upgrade: BooleanFlag, consentUpdate: boolean = false):
250
255
  }
251
256
  }
252
257
 
253
- function supported(target: Window | Document, api: string): boolean {
254
- try { return !!target[api]; } catch { return false; }
255
- }
256
-
257
258
  function track(u: User, consent: BooleanFlag = null): void {
258
259
  // If consent is not explicitly specified, infer it from the user object
259
260
  consent = consent === null ? u.consent : consent;
@@ -266,7 +267,7 @@ function track(u: User, consent: BooleanFlag = null): void {
266
267
  // To avoid cookie churn, write user id cookie only once every day
267
268
  if (u.expiry === null || Math.abs(end - u.expiry) >= Setting.CookieInterval || u.consent !== consent || u.dob !== dob) {
268
269
  let cookieParts = [data.userId, Setting.CookieVersion, end.toString(36), consent, dob];
269
- setCookie(Constant.CookieKey, cookieParts.join(Constant.Caret), Setting.Expire);
270
+ setCookie(Constant.CookieKey, cookieParts.join(COOKIE_SEP), Setting.Expire);
270
271
  }
271
272
  }
272
273
 
@@ -321,91 +322,3 @@ function user(): User {
321
322
  return output;
322
323
  }
323
324
 
324
- function getCookie(key: string, limit = false): string {
325
- if (supported(document, Constant.Cookie)) {
326
- let cookies: string[] = document.cookie.split(Constant.Semicolon);
327
- if (cookies) {
328
- for (let i = 0; i < cookies.length; i++) {
329
- let pair: string[] = cookies[i].split(Constant.Equals);
330
- if (pair.length > 1 && pair[0] && pair[0].trim() === key) {
331
- // Some browsers automatically url encode cookie values if they are not url encoded.
332
- // We therefore encode and decode cookie values ourselves.
333
- // For backwards compatability we need to consider 3 cases:
334
- // * Cookie was previously not encoded by Clarity and browser did not encode it
335
- // * Cookie was previously not encoded by Clarity and browser encoded it once or more
336
- // * Cookie was previously encoded by Clarity and browser did not encode it
337
- let [isEncoded, decodedValue] = decodeCookieValue(pair[1]);
338
-
339
- while (isEncoded) {
340
- [isEncoded, decodedValue] = decodeCookieValue(decodedValue);
341
- }
342
-
343
- // If we are limiting cookies, check if the cookie value is limited
344
- if (limit) {
345
- return decodedValue.endsWith(`${Constant.Tilde}1`)
346
- ? decodedValue.substring(0, decodedValue.length - 2)
347
- : null;
348
- }
349
-
350
- return decodedValue;
351
- }
352
- }
353
- }
354
- }
355
- return null;
356
- }
357
-
358
- function decodeCookieValue(value: string): [boolean, string] {
359
- try {
360
- let decodedValue = decodeURIComponent(value);
361
- return [decodedValue != value, decodedValue];
362
- }
363
- catch {
364
- }
365
-
366
- return [false, value];
367
- }
368
-
369
- function encodeCookieValue(value: string): string {
370
- return encodeURIComponent(value);
371
- }
372
-
373
- function setCookie(key: string, value: string, time: number): void {
374
- // only write cookies if we are currently in a cookie writing mode (and they are supported)
375
- // OR if we are trying to write an empty cookie (i.e. clear the cookie value out)
376
- if ((config.track || value == Constant.Empty) && ((navigator && navigator.cookieEnabled) || supported(document, Constant.Cookie))) {
377
- // Some browsers automatically url encode cookie values if they are not url encoded.
378
- // We therefore encode and decode cookie values ourselves.
379
- let encodedValue = encodeCookieValue(value);
380
-
381
- let expiry = new Date();
382
- expiry.setDate(expiry.getDate() + time);
383
- let expires = expiry ? Constant.Expires + expiry.toUTCString() : Constant.Empty;
384
- let cookie = `${key}=${encodedValue}${Constant.Semicolon}${expires}${Constant.Path}`;
385
- try {
386
- // Attempt to get the root domain only once and fall back to writing cookie on the current domain.
387
- if (rootDomain === null) {
388
- let hostname = location.hostname ? location.hostname.split(Constant.Dot) : [];
389
- // Walk backwards on a domain and attempt to set a cookie, until successful
390
- for (let i = hostname.length - 1; i >= 0; i--) {
391
- rootDomain = `.${hostname[i]}${rootDomain ? rootDomain : Constant.Empty}`;
392
- // We do not wish to attempt writing a cookie on the absolute last part of the domain, e.g. .com or .net.
393
- // So we start attempting after second-last part, e.g. .domain.com (PASS) or .co.uk (FAIL)
394
- if (i < hostname.length - 1) {
395
- // Write the cookie on the current computed top level domain
396
- document.cookie = `${cookie}${Constant.Semicolon}${Constant.Domain}${rootDomain}`;
397
- // Once written, check if the cookie exists and its value matches exactly with what we intended to set
398
- // Checking for exact value match helps us eliminate a corner case where the cookie may already be present with a different value
399
- // If the check is successful, no more action is required and we can return from the function since rootDomain cookie is already set
400
- // If the check fails, continue with the for loop until we can successfully set and verify the cookie
401
- if (getCookie(key) === value) { return; }
402
- }
403
- }
404
- // Finally, if we were not successful and gone through all the options, play it safe and reset rootDomain to be empty
405
- // This forces our code to fall back to always writing cookie to the current domain
406
- rootDomain = Constant.Empty;
407
- }
408
- } catch { rootDomain = Constant.Empty; }
409
- document.cookie = rootDomain ? `${cookie}${Constant.Semicolon}${Constant.Domain}${rootDomain}` : cookie;
410
- }
411
- }
@@ -0,0 +1,18 @@
1
+ export function supported(target: Window | Document, api: string): boolean {
2
+ try { return !!target[api]; } catch { return false; }
3
+ }
4
+
5
+ export function encodeCookieValue(value: string): string {
6
+ return encodeURIComponent(value);
7
+ }
8
+
9
+ export function decodeCookieValue(value: string): [boolean, string] {
10
+ try {
11
+ let decodedValue = decodeURIComponent(value);
12
+ return [decodedValue != value, decodedValue];
13
+ }
14
+ catch {
15
+ }
16
+
17
+ return [false, value];
18
+ }
package/src/index.ts CHANGED
@@ -3,7 +3,7 @@ import hash from "./core/hash";
3
3
  import * as selector from "./layout/selector";
4
4
  import { get, getNode, lookup } from "./layout/dom";
5
5
 
6
- const helper = { hash, selector, get, getNode, lookup };
6
+ const helper = { hash, selector, get, getNode, lookup }
7
7
  const version = clarity.version;
8
8
 
9
9
  export { clarity, version, helper };
@@ -38,7 +38,7 @@ export function metadata(node: Node): TargetMetadata {
38
38
  return output;
39
39
  }
40
40
 
41
- export function snapshot(): void {
41
+ export function snapshot(): void {
42
42
  values = [];
43
43
  traverse(document);
44
44
  encode(Event.Snapshot);
@@ -54,13 +54,13 @@ function traverse(root: Node): void {
54
54
  let attributes = null, tag = null, value = null;
55
55
  let node = queue.shift();
56
56
  let next = node.firstChild;
57
- let parent = node.parentElement ? node.parentElement : (node.parentNode ? node.parentNode : null);
57
+ let parent = node.parentElement ? node.parentElement : (node.parentNode ? node.parentNode : null);
58
58
 
59
59
  while (next) {
60
60
  queue.push(next);
61
61
  next = next.nextSibling;
62
62
  }
63
-
63
+
64
64
  // Process the node
65
65
  let type = node.nodeType;
66
66
  switch (type) {
@@ -69,7 +69,7 @@ function traverse(root: Node): void {
69
69
  tag = Constant.DocumentTag;
70
70
  attributes = { name: doctype.name, publicId: doctype.publicId, systemId: doctype.systemId }
71
71
  break;
72
- case Node.TEXT_NODE:
72
+ case Node.TEXT_NODE:
73
73
  value = node.nodeValue;
74
74
  tag = idMap.get(parent) ? Constant.TextTag : tag;
75
75
  break;
@@ -79,7 +79,7 @@ function traverse(root: Node): void {
79
79
  tag = ["NOSCRIPT", "SCRIPT", "STYLE"].indexOf(element.tagName) < 0 ? element.tagName : tag;
80
80
  break;
81
81
  }
82
- add(node, parent, { tag, attributes, value });
82
+ add(node, parent, { tag, attributes, value });
83
83
  }
84
84
  }
85
85
 
@@ -88,7 +88,7 @@ function getAttributes(element: HTMLElement): { [key: string]: string } {
88
88
  let output = {};
89
89
  let attributes = element.attributes;
90
90
  if (attributes && attributes.length > 0) {
91
- for (let i = 0; i < attributes.length; i++) {
91
+ for (let i = 0; i < attributes.length; i++) {
92
92
  output[attributes[i].name] = attributes[i].value;
93
93
  }
94
94
  }
@@ -112,4 +112,4 @@ function add(node: Node, parent: Node, data: NodeInfo): void {
112
112
  }
113
113
  }
114
114
 
115
- export function get(_node: Node): NodeValue { return null; }
115
+ export function get(_node: Node): NodeValue {return null;}
@@ -8,6 +8,7 @@ import * as interaction from "@src/interaction";
8
8
  import * as mutation from "@src/layout/mutation";
9
9
  import * as schema from "@src/layout/schema";
10
10
  import * as custom from "@src/layout/custom";
11
+ import * as dialogCustom from "@src/custom/dialog";
11
12
  import { checkDocumentStyles } from "@src/layout/style";
12
13
  import { electron } from "@src/data/metadata";
13
14
 
@@ -200,6 +201,13 @@ export default function (node: Node, source: Source, timestamp: number): Node {
200
201
  let mediaTag = { tag, attributes };
201
202
  dom[call](node, parent, mediaTag, source);
202
203
  break;
204
+ case "DIALOG":
205
+ // Use custom module for dialog tracking
206
+ let dialogElement = node as HTMLDialogElement;
207
+ let dialogTracking = dialogCustom.trackDialog(dialogElement, attributes);
208
+ let dialogData = dialogCustom.createDialogNodeData(tag, dialogTracking.attributes);
209
+ dom[call](node, parent, dialogData, source);
210
+ break;
203
211
  default:
204
212
  custom.check(element.localName);
205
213
  let data = { tag, attributes };
@@ -0,0 +1,68 @@
1
+ import { expect, test } from "@playwright/test";
2
+ import hash from "@src/core/hash";
3
+
4
+ test.describe("Core Utilities - Hash", () => {
5
+ test("hash function should generate consistent hash for same input", () => {
6
+ const input = "test-string";
7
+ const hash1 = hash(input);
8
+ const hash2 = hash(input);
9
+
10
+ expect(hash1).toBe(hash2);
11
+ expect(hash1).toBeTruthy();
12
+ expect(typeof hash1).toBe("string");
13
+ });
14
+
15
+ test("hash function should generate different hashes for different inputs", () => {
16
+ const hash1 = hash("input1");
17
+ const hash2 = hash("input2");
18
+ const hash3 = hash("completely-different-input");
19
+
20
+ expect(hash1).not.toBe(hash2);
21
+ expect(hash2).not.toBe(hash3);
22
+ expect(hash1).not.toBe(hash3);
23
+ });
24
+
25
+ test("hash function should respect precision parameter", () => {
26
+ const input = "test-precision";
27
+ const hashNoPrecision = hash(input);
28
+ const hash16 = hash(input, 16);
29
+ const hash8 = hash(input, 8);
30
+
31
+ expect(hashNoPrecision).toBeTruthy();
32
+ expect(hash16).toBeTruthy();
33
+ expect(hash8).toBeTruthy();
34
+
35
+ // Hash with precision should be different from no precision
36
+ expect(hashNoPrecision).not.toBe(hash16);
37
+
38
+ // Verify precision limits: 2^16 = 65536, 2^8 = 256
39
+ const hash16Num = parseInt(hash16, 36);
40
+ const hash8Num = parseInt(hash8, 36);
41
+ expect(hash16Num).toBeLessThan(65536);
42
+ expect(hash8Num).toBeLessThan(256);
43
+ });
44
+
45
+ test("hash function should handle empty strings", () => {
46
+ const result = hash("");
47
+ expect(result).toBeTruthy();
48
+ expect(typeof result).toBe("string");
49
+ });
50
+
51
+ test("hash function should handle special characters", () => {
52
+ const hash1 = hash("test@example.com");
53
+ const hash2 = hash("test#$%^&*()");
54
+ const hash3 = hash("🎉🎊✨");
55
+
56
+ expect(hash1).toBeTruthy();
57
+ expect(hash2).toBeTruthy();
58
+ expect(hash3).toBeTruthy();
59
+ expect(hash1).not.toBe(hash2);
60
+ expect(hash2).not.toBe(hash3);
61
+ });
62
+
63
+ test("hash function should produce base36 output", () => {
64
+ const result = hash("test-base36");
65
+ // Base36 should only contain 0-9 and a-z
66
+ expect(/^[0-9a-z]+$/.test(result)).toBe(true);
67
+ });
68
+ });
@@ -0,0 +1,42 @@
1
+ import { expect, test } from "@playwright/test";
2
+ import { start, stop, time } from "@src/core/time";
3
+
4
+ test.describe("Time Utilities", () => {
5
+ test("time module should start and stop", () => {
6
+ start();
7
+ const time1 = time();
8
+
9
+ expect(time1).toBeGreaterThanOrEqual(0);
10
+
11
+ stop();
12
+ const time2 = time();
13
+
14
+ // After stop, time should still work but use different baseline
15
+ expect(time2).toBeGreaterThanOrEqual(0);
16
+ });
17
+
18
+ test("time function should track elapsed time", async () => {
19
+ start();
20
+ const time1 = time();
21
+
22
+ // Wait a bit
23
+ await new Promise((resolve) => setTimeout(resolve, 50));
24
+
25
+ const time2 = time();
26
+
27
+ expect(time2).toBeGreaterThan(time1);
28
+ expect(time2 - time1).toBeGreaterThanOrEqual(50);
29
+
30
+ stop();
31
+ });
32
+
33
+ test("time function should handle null event parameter", () => {
34
+ start();
35
+ const result = time(null);
36
+
37
+ expect(result).toBeGreaterThanOrEqual(0);
38
+ expect(typeof result).toBe("number");
39
+
40
+ stop();
41
+ });
42
+ });
package/tsconfig.json CHANGED
@@ -1,21 +1,12 @@
1
1
  {
2
+ "extends": "../../tsconfig.json",
2
3
  "compilerOptions": {
3
- "module": "esnext",
4
- "target": "es5",
5
- "lib": ["es6", "dom", "es2016", "es2017"],
6
- "moduleResolution": "node",
7
- "forceConsistentCasingInFileNames": true,
8
- "noImplicitReturns": true,
9
- "noUnusedLocals": true,
10
- "noUnusedParameters": true,
11
- "resolveJsonModule": true,
12
- "esModuleInterop": true,
13
4
  "baseUrl": ".",
14
5
  "paths": {
15
6
  "@src/*": ["src/*"],
16
7
  "@clarity-types/*": ["types/*"]
17
8
  }
18
9
  },
19
- "include":["src/**/*.ts","types/**/*.d.ts", "rollup.config.ts"],
20
- "exclude": ["test", "node_modules", "build"]
10
+ "include":["src/**/*.ts", "types/**/*.d.ts", "test/**/*.ts", "rollup.config.ts"],
11
+ "exclude": ["node_modules", "build"]
21
12
  }
package/types/data.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  import { Time } from "@clarity-types/core";
2
- export type Target = number | Node;
3
- export type Token = string | number | number[] | string[] | (string | number)[];
4
- export type DecodedToken = any | any[];
2
+ export type Target = (number | Node);
3
+ export type Token = (string | number | number[] | string[] | (string | number)[]);
4
+ export type DecodedToken = (any | any[]);
5
5
 
6
6
  export type MetadataCallback = (data: Metadata, playback: boolean, consentStatus?: ConsentState) => void;
7
7
  export interface MetadataCallbackOptions {
8
- callback: MetadataCallback;
9
- wait: boolean;
10
- recall: boolean;
11
- called: boolean;
12
- consentInfo: boolean;
8
+ callback: MetadataCallback,
9
+ wait: boolean,
10
+ recall: boolean,
11
+ called: boolean,
12
+ consentInfo: boolean
13
13
  }
14
- export type SignalCallback = (data: ClaritySignal) => void;
14
+ export type SignalCallback = (data: ClaritySignal) => void
15
15
 
16
16
  /* Enum */
17
17
  export const enum Event {
@@ -87,7 +87,7 @@ export const enum Event {
87
87
  Keystrokes = 104,
88
88
  BackGesture = 105,
89
89
  WebViewStatus = 106,
90
- AppInstallReferrer = 107,
90
+ AppInstallReferrer = 107
91
91
  // 200-300 reserved for internal use
92
92
  }
93
93
 
@@ -182,7 +182,7 @@ export const enum Dimension {
182
182
  Timezone = 34,
183
183
  TimezoneOffset = 35,
184
184
  Consent = 36,
185
- InteractionNextPaint = 37,
185
+ InteractionNextPaint = 37
186
186
  // 200-300 reserved for internal use
187
187
  }
188
188
 
@@ -194,7 +194,7 @@ export const enum Check {
194
194
  Bytes = 4,
195
195
  Collection = 5,
196
196
  Server = 6,
197
- Page = 7,
197
+ Page = 7
198
198
  }
199
199
 
200
200
  export const enum Code {
@@ -218,29 +218,29 @@ export const enum Severity {
218
218
  Info = 0,
219
219
  Warning = 1,
220
220
  Error = 2,
221
- Fatal = 3,
221
+ Fatal = 3
222
222
  }
223
223
 
224
224
  export const enum Upload {
225
225
  Async = 0,
226
- Beacon = 1,
226
+ Beacon = 1
227
227
  }
228
228
 
229
229
  export const enum BooleanFlag {
230
230
  False = 0,
231
- True = 1,
231
+ True = 1
232
232
  }
233
233
 
234
234
  export const enum GCMConsent {
235
235
  Unknown = 0,
236
236
  Granted = 1,
237
- Denied = 2,
237
+ Denied = 2
238
238
  }
239
239
 
240
240
  export const enum IframeStatus {
241
241
  Unknown = 0,
242
242
  TopFrame = 1,
243
- Iframe = 2,
243
+ Iframe = 2
244
244
  }
245
245
 
246
246
  export const enum Setting {
@@ -291,17 +291,17 @@ export const enum Character {
291
291
  Blank = 32,
292
292
  Tab = 9,
293
293
  NewLine = 10,
294
- Return = 13,
294
+ Return = 13
295
295
  }
296
296
 
297
297
  export const enum ApplicationPlatform {
298
- WebApp = 0,
298
+ WebApp = 0
299
299
  }
300
300
 
301
301
  export const enum Constant {
302
302
  Auto = "Auto",
303
303
  Config = "Config",
304
- Clarity = "clarity",
304
+ Clarity = "clarityGemX",
305
305
  Restart = "restart",
306
306
  Suspend = "suspend",
307
307
  Pause = "pause",
@@ -380,27 +380,36 @@ export const enum XMLReadyState {
380
380
  Opened = 1,
381
381
  Headers_Recieved = 2,
382
382
  Loading = 3,
383
- Done = 4,
383
+ Done = 4
384
384
  }
385
385
 
386
386
  export const enum ConsentSource {
387
387
  Implicit = 0,
388
388
  API = 1,
389
389
  GCM = 2,
390
+ TCF = 3,
391
+ APIv1 = 4,
392
+ APIv2 = 5,
393
+ Cookie = 6,
394
+ Default = 7,
395
+ // 100-255 Reserved for CMP integration, both internal and external
396
+ ClarityShopifyPixel = 100,
397
+ ClarityShopifyApp = 101,
398
+ UET = 102
390
399
  }
391
400
 
392
401
  /* Helper Interfaces */
393
402
 
394
403
  export interface Payload {
395
- e: Token[] /* Envelope */;
396
- a: Token[][] /* Events that are used for data analysis */;
397
- p: Token[][] /* Events that are primarily used for session playback */;
404
+ e: Token[]; /* Envelope */
405
+ a: Token[][]; /* Events that are used for data analysis */
406
+ p: Token[][]; /* Events that are primarily used for session playback */
398
407
  }
399
408
 
400
409
  export interface EncodedPayload {
401
- e: string /* Envelope */;
402
- a: string /* Analytics Payload */;
403
- p: string /* Playback Payload */;
410
+ e: string; /* Envelope */
411
+ a: string; /* Analytics Payload */
412
+ p: string; /* Playback Payload */
404
413
  }
405
414
 
406
415
  export interface Metadata {
@@ -534,8 +543,8 @@ export interface UploadData {
534
543
  }
535
544
 
536
545
  export interface ClaritySignal {
537
- type: string;
538
- value?: number;
546
+ type: string
547
+ value?: number
539
548
  }
540
549
 
541
550
  export interface PerformanceEventTiming extends PerformanceEntry {
@@ -557,7 +566,7 @@ export interface ConsentState {
557
566
  export const enum ConsentType {
558
567
  None = 0,
559
568
  Implicit = 1,
560
- General = 2,
569
+ General = 2
561
570
  }
562
571
 
563
572
  export interface ConsentData {
package/types/index.d.ts CHANGED
@@ -11,12 +11,12 @@ interface Clarity {
11
11
  pause: () => void;
12
12
  resume: () => void;
13
13
  upgrade: (key: string) => void;
14
- consent: () => void;
15
- consentv2: () => void;
14
+ consent: (status?: boolean) => void;
15
+ consentv2: (consentState?: Data.ConsentState, source?: number) => void;
16
16
  event: (name: string, value: string) => void;
17
17
  set: (variable: string, value: string | string[]) => void;
18
18
  identify: (userId: string, sessionId?: string, pageId?: string, userHint?: string) => void;
19
- metadata: (callback: Data.MetadataCallback, wait?: boolean) => void;
19
+ metadata: (callback: Data.MetadataCallback, wait?: boolean, recall?: boolean, consentInfo?: boolean) => void;
20
20
  signal: (callback: Data.SignalCallback) => void;
21
21
  }
22
22