aurea-tracking-sdk 1.3.4 → 1.5.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/dist/index.d.mts CHANGED
@@ -31,6 +31,11 @@ interface AureaConfig {
31
31
  };
32
32
  autoAdvanceStages?: boolean;
33
33
  customStages?: string[];
34
+ gdprConsent?: {
35
+ required: boolean;
36
+ onConsentRequired?: () => Promise<boolean>;
37
+ consentVersion?: string;
38
+ };
34
39
  }
35
40
  interface TrackingEvent {
36
41
  eventId: string;
@@ -132,15 +137,35 @@ declare class AureaSDK {
132
137
  private checkoutStartedAt?;
133
138
  private eventCategoryStats;
134
139
  private trackedOnceEvents;
140
+ private consentGiven;
141
+ private consentVersion;
135
142
  constructor(config: AureaConfig);
136
143
  /**
137
144
  * Initialize the SDK
138
145
  */
139
- init(): void;
146
+ init(): Promise<void>;
140
147
  /**
141
148
  * Track a custom event
142
149
  */
143
150
  track(eventName: string, properties?: Record<string, any>): void;
151
+ /**
152
+ * Grant GDPR consent
153
+ * Call this when user accepts your privacy policy/cookie banner
154
+ */
155
+ grantConsent(version?: string): void;
156
+ /**
157
+ * Revoke GDPR consent
158
+ * Call this when user revokes consent (e.g., via cookie settings)
159
+ */
160
+ revokeConsent(): void;
161
+ /**
162
+ * Check if consent has been given
163
+ */
164
+ hasConsent(): boolean;
165
+ /**
166
+ * Request data deletion (Right to be Forgotten)
167
+ */
168
+ requestDataDeletion(): Promise<void>;
144
169
  /**
145
170
  * Identify a user (links anonymous user to known user)
146
171
  */
@@ -331,6 +356,10 @@ declare class AureaSDK {
331
356
  * Check if user has completed a purchase
332
357
  */
333
358
  private checkForPurchase;
359
+ /**
360
+ * Send Web Vital to dedicated endpoint
361
+ */
362
+ private sendWebVital;
334
363
  /**
335
364
  * Track Core Web Vitals
336
365
  */
package/dist/index.d.ts CHANGED
@@ -31,6 +31,11 @@ interface AureaConfig {
31
31
  };
32
32
  autoAdvanceStages?: boolean;
33
33
  customStages?: string[];
34
+ gdprConsent?: {
35
+ required: boolean;
36
+ onConsentRequired?: () => Promise<boolean>;
37
+ consentVersion?: string;
38
+ };
34
39
  }
35
40
  interface TrackingEvent {
36
41
  eventId: string;
@@ -132,15 +137,35 @@ declare class AureaSDK {
132
137
  private checkoutStartedAt?;
133
138
  private eventCategoryStats;
134
139
  private trackedOnceEvents;
140
+ private consentGiven;
141
+ private consentVersion;
135
142
  constructor(config: AureaConfig);
136
143
  /**
137
144
  * Initialize the SDK
138
145
  */
139
- init(): void;
146
+ init(): Promise<void>;
140
147
  /**
141
148
  * Track a custom event
142
149
  */
143
150
  track(eventName: string, properties?: Record<string, any>): void;
151
+ /**
152
+ * Grant GDPR consent
153
+ * Call this when user accepts your privacy policy/cookie banner
154
+ */
155
+ grantConsent(version?: string): void;
156
+ /**
157
+ * Revoke GDPR consent
158
+ * Call this when user revokes consent (e.g., via cookie settings)
159
+ */
160
+ revokeConsent(): void;
161
+ /**
162
+ * Check if consent has been given
163
+ */
164
+ hasConsent(): boolean;
165
+ /**
166
+ * Request data deletion (Right to be Forgotten)
167
+ */
168
+ requestDataDeletion(): Promise<void>;
144
169
  /**
145
170
  * Identify a user (links anonymous user to known user)
146
171
  */
@@ -331,6 +356,10 @@ declare class AureaSDK {
331
356
  * Check if user has completed a purchase
332
357
  */
333
358
  private checkForPurchase;
359
+ /**
360
+ * Send Web Vital to dedicated endpoint
361
+ */
362
+ private sendWebVital;
334
363
  /**
335
364
  * Track Core Web Vitals
336
365
  */
package/dist/index.js CHANGED
@@ -55,6 +55,9 @@ var AureaSDK = class {
55
55
  this.eventCategoryStats = /* @__PURE__ */ new Map();
56
56
  // NEW: Track which events have been fired (for trackOnce behavior)
57
57
  this.trackedOnceEvents = /* @__PURE__ */ new Set();
58
+ // GDPR: Consent tracking
59
+ this.consentGiven = false;
60
+ this.consentVersion = "1.0";
58
61
  this.config = {
59
62
  apiUrl: "http://localhost:3000/api",
60
63
  debug: false,
@@ -77,12 +80,18 @@ var AureaSDK = class {
77
80
  if (savedUserId) {
78
81
  this.userId = savedUserId;
79
82
  }
83
+ const savedConsent = localStorage.getItem("aurea_consent");
84
+ const savedConsentVersion = localStorage.getItem("aurea_consent_version");
85
+ if (savedConsent === "granted" && savedConsentVersion) {
86
+ this.consentGiven = true;
87
+ this.consentVersion = savedConsentVersion;
88
+ }
80
89
  }
81
90
  }
82
91
  /**
83
92
  * Initialize the SDK
84
93
  */
85
- init() {
94
+ async init() {
86
95
  if (this.initialized) {
87
96
  console.warn("[Aurea SDK] Already initialized");
88
97
  return;
@@ -93,6 +102,29 @@ var AureaSDK = class {
93
102
  }
94
103
  return;
95
104
  }
105
+ if (this.config.gdprConsent?.required) {
106
+ if (!this.consentGiven) {
107
+ if (this.config.debug) {
108
+ console.log("[Aurea SDK] GDPR consent required but not given");
109
+ }
110
+ if (this.config.gdprConsent.onConsentRequired) {
111
+ const consentGranted = await this.config.gdprConsent.onConsentRequired();
112
+ if (consentGranted) {
113
+ this.grantConsent(this.config.gdprConsent.consentVersion || "1.0");
114
+ } else {
115
+ if (this.config.debug) {
116
+ console.log("[Aurea SDK] Consent not granted, tracking disabled");
117
+ }
118
+ return;
119
+ }
120
+ } else {
121
+ if (this.config.debug) {
122
+ console.log("[Aurea SDK] Waiting for manual consent via grantConsent()");
123
+ }
124
+ return;
125
+ }
126
+ }
127
+ }
96
128
  this.initialized = true;
97
129
  if (this.config.autoTrack?.pageViews) {
98
130
  this.trackPageLoad();
@@ -134,6 +166,87 @@ var AureaSDK = class {
134
166
  console.log("[Aurea SDK] Event tracked:", eventName, properties);
135
167
  }
136
168
  }
169
+ /**
170
+ * Grant GDPR consent
171
+ * Call this when user accepts your privacy policy/cookie banner
172
+ */
173
+ grantConsent(version = "1.0") {
174
+ this.consentGiven = true;
175
+ this.consentVersion = version;
176
+ if (typeof window !== "undefined") {
177
+ localStorage.setItem("aurea_consent", "granted");
178
+ localStorage.setItem("aurea_consent_version", version);
179
+ localStorage.setItem("aurea_consent_timestamp", (/* @__PURE__ */ new Date()).toISOString());
180
+ }
181
+ this.track("consent_granted", {
182
+ consentVersion: version,
183
+ timestamp: Date.now()
184
+ });
185
+ if (!this.initialized) {
186
+ this.init();
187
+ }
188
+ if (this.config.debug) {
189
+ console.log("[Aurea SDK] Consent granted:", version);
190
+ }
191
+ }
192
+ /**
193
+ * Revoke GDPR consent
194
+ * Call this when user revokes consent (e.g., via cookie settings)
195
+ */
196
+ revokeConsent() {
197
+ this.consentGiven = false;
198
+ if (typeof window !== "undefined") {
199
+ localStorage.removeItem("aurea_consent");
200
+ localStorage.removeItem("aurea_consent_version");
201
+ localStorage.removeItem("aurea_consent_timestamp");
202
+ }
203
+ this.track("consent_revoked", {
204
+ timestamp: Date.now()
205
+ });
206
+ this.initialized = false;
207
+ if (this.config.debug) {
208
+ console.log("[Aurea SDK] Consent revoked, tracking stopped");
209
+ }
210
+ }
211
+ /**
212
+ * Check if consent has been given
213
+ */
214
+ hasConsent() {
215
+ return this.consentGiven;
216
+ }
217
+ /**
218
+ * Request data deletion (Right to be Forgotten)
219
+ */
220
+ async requestDataDeletion() {
221
+ try {
222
+ await fetch(`${this.config.apiUrl}/track/delete`, {
223
+ method: "POST",
224
+ headers: {
225
+ "Content-Type": "application/json",
226
+ "X-Aurea-API-Key": this.config.apiKey,
227
+ "X-Aurea-Funnel-ID": this.config.funnelId
228
+ },
229
+ body: JSON.stringify({
230
+ anonymousId: this.anonymousId,
231
+ userId: this.userId
232
+ })
233
+ });
234
+ if (typeof window !== "undefined") {
235
+ localStorage.removeItem("aurea_anonymous_id");
236
+ localStorage.removeItem("aurea_user_id");
237
+ localStorage.removeItem("aurea_consent");
238
+ localStorage.removeItem("aurea_consent_version");
239
+ localStorage.removeItem("aurea_consent_timestamp");
240
+ sessionStorage.removeItem("aurea_session_id");
241
+ }
242
+ if (this.config.debug) {
243
+ console.log("[Aurea SDK] Data deletion requested");
244
+ }
245
+ } catch (error) {
246
+ console.error("[Aurea SDK] Failed to request data deletion:", error);
247
+ throw error;
248
+ }
249
+ }
137
250
  /**
138
251
  * Identify a user (links anonymous user to known user)
139
252
  */
@@ -550,9 +663,6 @@ var AureaSDK = class {
550
663
  async endSession() {
551
664
  if (typeof window === "undefined") return;
552
665
  const now = Date.now();
553
- if (this.isInCheckout && this.currentStage === "checkout") {
554
- this.checkoutAbandoned("session_end");
555
- }
556
666
  if (this.isPageVisible) {
557
667
  this.activeTime += now - this.lastActiveTimestamp;
558
668
  }
@@ -649,12 +759,15 @@ var AureaSDK = class {
649
759
  } else {
650
760
  const aspectRatio = screenWidth / screenHeight;
651
761
  const userAgent = navigator.userAgent.toLowerCase();
652
- const isLaptopUA = userAgent.includes("macintosh") || // MacBooks
653
- userAgent.includes("mac os x") || userAgent.includes("laptop") || userAgent.includes("windows") && userAgent.includes("touch") || // Windows laptops with touch
654
- userAgent.includes("chromebook");
762
+ const isMac = userAgent.includes("macintosh") || userAgent.includes("mac os x");
763
+ const isWindowsLaptop = userAgent.includes("windows") && userAgent.includes("touch");
764
+ const isChromebook = userAgent.includes("chromebook") || userAgent.includes("cros");
765
+ const hasLaptopKeyword = userAgent.includes("laptop");
655
766
  if (screenWidth >= 2560 || aspectRatio >= 2.2) {
656
767
  deviceType = "Ultrawide";
657
- } else if (screenWidth <= 2048 && (isLaptopUA || screenWidth < 1920)) {
768
+ } else if (screenWidth <= 1920) {
769
+ deviceType = "Laptop";
770
+ } else if (screenWidth <= 2048 && (isWindowsLaptop || isChromebook || hasLaptopKeyword)) {
658
771
  deviceType = "Laptop";
659
772
  } else {
660
773
  deviceType = "Desktop";
@@ -699,6 +812,11 @@ var AureaSDK = class {
699
812
  session: {
700
813
  sessionId: this.sessionId
701
814
  },
815
+ gdpr: {
816
+ consentGiven: this.consentGiven,
817
+ consentVersion: this.consentVersion,
818
+ consentTimestamp: typeof window !== "undefined" ? localStorage.getItem("aurea_consent_timestamp") || void 0 : void 0
819
+ },
702
820
  device: typeof navigator !== "undefined" ? this.parseDeviceInfo() : void 0
703
821
  };
704
822
  }
@@ -883,6 +1001,49 @@ var AureaSDK = class {
883
1001
  }
884
1002
  }
885
1003
  }
1004
+ /**
1005
+ * Send Web Vital to dedicated endpoint
1006
+ */
1007
+ async sendWebVital(metric, name, rating) {
1008
+ try {
1009
+ const deviceInfo = this.parseDeviceInfo();
1010
+ await fetch(`${this.config.apiUrl}/track/web-vitals`, {
1011
+ method: "POST",
1012
+ headers: {
1013
+ "Content-Type": "application/json",
1014
+ "X-Aurea-API-Key": this.config.apiKey,
1015
+ "X-Aurea-Funnel-ID": this.config.funnelId
1016
+ },
1017
+ body: JSON.stringify({
1018
+ funnelId: this.config.funnelId,
1019
+ sessionId: this.sessionId,
1020
+ anonymousId: this.anonymousId,
1021
+ pageUrl: window.location.href,
1022
+ pagePath: window.location.pathname,
1023
+ pageTitle: document.title,
1024
+ metric: name.toUpperCase(),
1025
+ value: metric.value,
1026
+ rating: rating.toUpperCase().replace("-", "_"),
1027
+ delta: metric.delta,
1028
+ id_metric: metric.id,
1029
+ deviceType: deviceInfo?.deviceType,
1030
+ browserName: deviceInfo?.browserName,
1031
+ browserVersion: deviceInfo?.browserVersion,
1032
+ osName: deviceInfo?.osName,
1033
+ osVersion: deviceInfo?.osVersion,
1034
+ screenWidth: deviceInfo?.screenWidth,
1035
+ screenHeight: deviceInfo?.screenHeight,
1036
+ timestamp: /* @__PURE__ */ new Date()
1037
+ }),
1038
+ keepalive: true
1039
+ });
1040
+ if (this.config.debug) {
1041
+ console.log(`[Aurea SDK] Web Vital sent: ${name}`, metric.value, rating);
1042
+ }
1043
+ } catch (error) {
1044
+ console.error(`[Aurea SDK] Failed to send ${name}:`, error);
1045
+ }
1046
+ }
886
1047
  /**
887
1048
  * Track Core Web Vitals
888
1049
  */
@@ -904,61 +1065,36 @@ var AureaSDK = class {
904
1065
  (0, import_web_vitals.onLCP)((metric) => {
905
1066
  if (!this.webVitalsCollected.lcp) {
906
1067
  this.webVitalsCollected.lcp = true;
907
- this.track("web_vital", {
908
- metric: "lcp",
909
- value: metric.value,
910
- rating: getVitalRating("LCP", metric.value),
911
- delta: metric.delta,
912
- id: metric.id
913
- });
1068
+ const rating = getVitalRating("LCP", metric.value);
1069
+ this.sendWebVital(metric, "lcp", rating);
914
1070
  }
915
1071
  });
916
1072
  (0, import_web_vitals.onINP)((metric) => {
917
1073
  if (!this.webVitalsCollected.inp) {
918
1074
  this.webVitalsCollected.inp = true;
919
- this.track("web_vital", {
920
- metric: "inp",
921
- value: metric.value,
922
- rating: getVitalRating("INP", metric.value),
923
- delta: metric.delta,
924
- id: metric.id
925
- });
1075
+ const rating = getVitalRating("INP", metric.value);
1076
+ this.sendWebVital(metric, "inp", rating);
926
1077
  }
927
1078
  });
928
1079
  (0, import_web_vitals.onCLS)((metric) => {
929
1080
  if (!this.webVitalsCollected.cls) {
930
1081
  this.webVitalsCollected.cls = true;
931
- this.track("web_vital", {
932
- metric: "cls",
933
- value: metric.value,
934
- rating: getVitalRating("CLS", metric.value),
935
- delta: metric.delta,
936
- id: metric.id
937
- });
1082
+ const rating = getVitalRating("CLS", metric.value);
1083
+ this.sendWebVital(metric, "cls", rating);
938
1084
  }
939
1085
  });
940
1086
  (0, import_web_vitals.onFCP)((metric) => {
941
1087
  if (!this.webVitalsCollected.fcp) {
942
1088
  this.webVitalsCollected.fcp = true;
943
- this.track("web_vital", {
944
- metric: "fcp",
945
- value: metric.value,
946
- rating: getVitalRating("FCP", metric.value),
947
- delta: metric.delta,
948
- id: metric.id
949
- });
1089
+ const rating = getVitalRating("FCP", metric.value);
1090
+ this.sendWebVital(metric, "fcp", rating);
950
1091
  }
951
1092
  });
952
1093
  (0, import_web_vitals.onTTFB)((metric) => {
953
1094
  if (!this.webVitalsCollected.ttfb) {
954
1095
  this.webVitalsCollected.ttfb = true;
955
- this.track("web_vital", {
956
- metric: "ttfb",
957
- value: metric.value,
958
- rating: getVitalRating("TTFB", metric.value),
959
- delta: metric.delta,
960
- id: metric.id
961
- });
1096
+ const rating = getVitalRating("TTFB", metric.value);
1097
+ this.sendWebVital(metric, "ttfb", rating);
962
1098
  }
963
1099
  });
964
1100
  if (this.config.debug) {
@@ -1004,9 +1140,6 @@ var AureaSDK = class {
1004
1140
  window.addEventListener("touchstart", resetInactivityTimer, { passive: true });
1005
1141
  window.addEventListener("beforeunload", () => {
1006
1142
  const now = Date.now();
1007
- if (this.isInCheckout && this.currentStage === "checkout") {
1008
- this.checkoutAbandoned("page_close");
1009
- }
1010
1143
  if (this.isPageVisible) {
1011
1144
  this.activeTime += now - this.lastActiveTimestamp;
1012
1145
  }
package/dist/index.mjs CHANGED
@@ -26,6 +26,9 @@ var AureaSDK = class {
26
26
  this.eventCategoryStats = /* @__PURE__ */ new Map();
27
27
  // NEW: Track which events have been fired (for trackOnce behavior)
28
28
  this.trackedOnceEvents = /* @__PURE__ */ new Set();
29
+ // GDPR: Consent tracking
30
+ this.consentGiven = false;
31
+ this.consentVersion = "1.0";
29
32
  this.config = {
30
33
  apiUrl: "http://localhost:3000/api",
31
34
  debug: false,
@@ -48,12 +51,18 @@ var AureaSDK = class {
48
51
  if (savedUserId) {
49
52
  this.userId = savedUserId;
50
53
  }
54
+ const savedConsent = localStorage.getItem("aurea_consent");
55
+ const savedConsentVersion = localStorage.getItem("aurea_consent_version");
56
+ if (savedConsent === "granted" && savedConsentVersion) {
57
+ this.consentGiven = true;
58
+ this.consentVersion = savedConsentVersion;
59
+ }
51
60
  }
52
61
  }
53
62
  /**
54
63
  * Initialize the SDK
55
64
  */
56
- init() {
65
+ async init() {
57
66
  if (this.initialized) {
58
67
  console.warn("[Aurea SDK] Already initialized");
59
68
  return;
@@ -64,6 +73,29 @@ var AureaSDK = class {
64
73
  }
65
74
  return;
66
75
  }
76
+ if (this.config.gdprConsent?.required) {
77
+ if (!this.consentGiven) {
78
+ if (this.config.debug) {
79
+ console.log("[Aurea SDK] GDPR consent required but not given");
80
+ }
81
+ if (this.config.gdprConsent.onConsentRequired) {
82
+ const consentGranted = await this.config.gdprConsent.onConsentRequired();
83
+ if (consentGranted) {
84
+ this.grantConsent(this.config.gdprConsent.consentVersion || "1.0");
85
+ } else {
86
+ if (this.config.debug) {
87
+ console.log("[Aurea SDK] Consent not granted, tracking disabled");
88
+ }
89
+ return;
90
+ }
91
+ } else {
92
+ if (this.config.debug) {
93
+ console.log("[Aurea SDK] Waiting for manual consent via grantConsent()");
94
+ }
95
+ return;
96
+ }
97
+ }
98
+ }
67
99
  this.initialized = true;
68
100
  if (this.config.autoTrack?.pageViews) {
69
101
  this.trackPageLoad();
@@ -105,6 +137,87 @@ var AureaSDK = class {
105
137
  console.log("[Aurea SDK] Event tracked:", eventName, properties);
106
138
  }
107
139
  }
140
+ /**
141
+ * Grant GDPR consent
142
+ * Call this when user accepts your privacy policy/cookie banner
143
+ */
144
+ grantConsent(version = "1.0") {
145
+ this.consentGiven = true;
146
+ this.consentVersion = version;
147
+ if (typeof window !== "undefined") {
148
+ localStorage.setItem("aurea_consent", "granted");
149
+ localStorage.setItem("aurea_consent_version", version);
150
+ localStorage.setItem("aurea_consent_timestamp", (/* @__PURE__ */ new Date()).toISOString());
151
+ }
152
+ this.track("consent_granted", {
153
+ consentVersion: version,
154
+ timestamp: Date.now()
155
+ });
156
+ if (!this.initialized) {
157
+ this.init();
158
+ }
159
+ if (this.config.debug) {
160
+ console.log("[Aurea SDK] Consent granted:", version);
161
+ }
162
+ }
163
+ /**
164
+ * Revoke GDPR consent
165
+ * Call this when user revokes consent (e.g., via cookie settings)
166
+ */
167
+ revokeConsent() {
168
+ this.consentGiven = false;
169
+ if (typeof window !== "undefined") {
170
+ localStorage.removeItem("aurea_consent");
171
+ localStorage.removeItem("aurea_consent_version");
172
+ localStorage.removeItem("aurea_consent_timestamp");
173
+ }
174
+ this.track("consent_revoked", {
175
+ timestamp: Date.now()
176
+ });
177
+ this.initialized = false;
178
+ if (this.config.debug) {
179
+ console.log("[Aurea SDK] Consent revoked, tracking stopped");
180
+ }
181
+ }
182
+ /**
183
+ * Check if consent has been given
184
+ */
185
+ hasConsent() {
186
+ return this.consentGiven;
187
+ }
188
+ /**
189
+ * Request data deletion (Right to be Forgotten)
190
+ */
191
+ async requestDataDeletion() {
192
+ try {
193
+ await fetch(`${this.config.apiUrl}/track/delete`, {
194
+ method: "POST",
195
+ headers: {
196
+ "Content-Type": "application/json",
197
+ "X-Aurea-API-Key": this.config.apiKey,
198
+ "X-Aurea-Funnel-ID": this.config.funnelId
199
+ },
200
+ body: JSON.stringify({
201
+ anonymousId: this.anonymousId,
202
+ userId: this.userId
203
+ })
204
+ });
205
+ if (typeof window !== "undefined") {
206
+ localStorage.removeItem("aurea_anonymous_id");
207
+ localStorage.removeItem("aurea_user_id");
208
+ localStorage.removeItem("aurea_consent");
209
+ localStorage.removeItem("aurea_consent_version");
210
+ localStorage.removeItem("aurea_consent_timestamp");
211
+ sessionStorage.removeItem("aurea_session_id");
212
+ }
213
+ if (this.config.debug) {
214
+ console.log("[Aurea SDK] Data deletion requested");
215
+ }
216
+ } catch (error) {
217
+ console.error("[Aurea SDK] Failed to request data deletion:", error);
218
+ throw error;
219
+ }
220
+ }
108
221
  /**
109
222
  * Identify a user (links anonymous user to known user)
110
223
  */
@@ -521,9 +634,6 @@ var AureaSDK = class {
521
634
  async endSession() {
522
635
  if (typeof window === "undefined") return;
523
636
  const now = Date.now();
524
- if (this.isInCheckout && this.currentStage === "checkout") {
525
- this.checkoutAbandoned("session_end");
526
- }
527
637
  if (this.isPageVisible) {
528
638
  this.activeTime += now - this.lastActiveTimestamp;
529
639
  }
@@ -620,12 +730,15 @@ var AureaSDK = class {
620
730
  } else {
621
731
  const aspectRatio = screenWidth / screenHeight;
622
732
  const userAgent = navigator.userAgent.toLowerCase();
623
- const isLaptopUA = userAgent.includes("macintosh") || // MacBooks
624
- userAgent.includes("mac os x") || userAgent.includes("laptop") || userAgent.includes("windows") && userAgent.includes("touch") || // Windows laptops with touch
625
- userAgent.includes("chromebook");
733
+ const isMac = userAgent.includes("macintosh") || userAgent.includes("mac os x");
734
+ const isWindowsLaptop = userAgent.includes("windows") && userAgent.includes("touch");
735
+ const isChromebook = userAgent.includes("chromebook") || userAgent.includes("cros");
736
+ const hasLaptopKeyword = userAgent.includes("laptop");
626
737
  if (screenWidth >= 2560 || aspectRatio >= 2.2) {
627
738
  deviceType = "Ultrawide";
628
- } else if (screenWidth <= 2048 && (isLaptopUA || screenWidth < 1920)) {
739
+ } else if (screenWidth <= 1920) {
740
+ deviceType = "Laptop";
741
+ } else if (screenWidth <= 2048 && (isWindowsLaptop || isChromebook || hasLaptopKeyword)) {
629
742
  deviceType = "Laptop";
630
743
  } else {
631
744
  deviceType = "Desktop";
@@ -670,6 +783,11 @@ var AureaSDK = class {
670
783
  session: {
671
784
  sessionId: this.sessionId
672
785
  },
786
+ gdpr: {
787
+ consentGiven: this.consentGiven,
788
+ consentVersion: this.consentVersion,
789
+ consentTimestamp: typeof window !== "undefined" ? localStorage.getItem("aurea_consent_timestamp") || void 0 : void 0
790
+ },
673
791
  device: typeof navigator !== "undefined" ? this.parseDeviceInfo() : void 0
674
792
  };
675
793
  }
@@ -854,6 +972,49 @@ var AureaSDK = class {
854
972
  }
855
973
  }
856
974
  }
975
+ /**
976
+ * Send Web Vital to dedicated endpoint
977
+ */
978
+ async sendWebVital(metric, name, rating) {
979
+ try {
980
+ const deviceInfo = this.parseDeviceInfo();
981
+ await fetch(`${this.config.apiUrl}/track/web-vitals`, {
982
+ method: "POST",
983
+ headers: {
984
+ "Content-Type": "application/json",
985
+ "X-Aurea-API-Key": this.config.apiKey,
986
+ "X-Aurea-Funnel-ID": this.config.funnelId
987
+ },
988
+ body: JSON.stringify({
989
+ funnelId: this.config.funnelId,
990
+ sessionId: this.sessionId,
991
+ anonymousId: this.anonymousId,
992
+ pageUrl: window.location.href,
993
+ pagePath: window.location.pathname,
994
+ pageTitle: document.title,
995
+ metric: name.toUpperCase(),
996
+ value: metric.value,
997
+ rating: rating.toUpperCase().replace("-", "_"),
998
+ delta: metric.delta,
999
+ id_metric: metric.id,
1000
+ deviceType: deviceInfo?.deviceType,
1001
+ browserName: deviceInfo?.browserName,
1002
+ browserVersion: deviceInfo?.browserVersion,
1003
+ osName: deviceInfo?.osName,
1004
+ osVersion: deviceInfo?.osVersion,
1005
+ screenWidth: deviceInfo?.screenWidth,
1006
+ screenHeight: deviceInfo?.screenHeight,
1007
+ timestamp: /* @__PURE__ */ new Date()
1008
+ }),
1009
+ keepalive: true
1010
+ });
1011
+ if (this.config.debug) {
1012
+ console.log(`[Aurea SDK] Web Vital sent: ${name}`, metric.value, rating);
1013
+ }
1014
+ } catch (error) {
1015
+ console.error(`[Aurea SDK] Failed to send ${name}:`, error);
1016
+ }
1017
+ }
857
1018
  /**
858
1019
  * Track Core Web Vitals
859
1020
  */
@@ -875,61 +1036,36 @@ var AureaSDK = class {
875
1036
  onLCP((metric) => {
876
1037
  if (!this.webVitalsCollected.lcp) {
877
1038
  this.webVitalsCollected.lcp = true;
878
- this.track("web_vital", {
879
- metric: "lcp",
880
- value: metric.value,
881
- rating: getVitalRating("LCP", metric.value),
882
- delta: metric.delta,
883
- id: metric.id
884
- });
1039
+ const rating = getVitalRating("LCP", metric.value);
1040
+ this.sendWebVital(metric, "lcp", rating);
885
1041
  }
886
1042
  });
887
1043
  onINP((metric) => {
888
1044
  if (!this.webVitalsCollected.inp) {
889
1045
  this.webVitalsCollected.inp = true;
890
- this.track("web_vital", {
891
- metric: "inp",
892
- value: metric.value,
893
- rating: getVitalRating("INP", metric.value),
894
- delta: metric.delta,
895
- id: metric.id
896
- });
1046
+ const rating = getVitalRating("INP", metric.value);
1047
+ this.sendWebVital(metric, "inp", rating);
897
1048
  }
898
1049
  });
899
1050
  onCLS((metric) => {
900
1051
  if (!this.webVitalsCollected.cls) {
901
1052
  this.webVitalsCollected.cls = true;
902
- this.track("web_vital", {
903
- metric: "cls",
904
- value: metric.value,
905
- rating: getVitalRating("CLS", metric.value),
906
- delta: metric.delta,
907
- id: metric.id
908
- });
1053
+ const rating = getVitalRating("CLS", metric.value);
1054
+ this.sendWebVital(metric, "cls", rating);
909
1055
  }
910
1056
  });
911
1057
  onFCP((metric) => {
912
1058
  if (!this.webVitalsCollected.fcp) {
913
1059
  this.webVitalsCollected.fcp = true;
914
- this.track("web_vital", {
915
- metric: "fcp",
916
- value: metric.value,
917
- rating: getVitalRating("FCP", metric.value),
918
- delta: metric.delta,
919
- id: metric.id
920
- });
1060
+ const rating = getVitalRating("FCP", metric.value);
1061
+ this.sendWebVital(metric, "fcp", rating);
921
1062
  }
922
1063
  });
923
1064
  onTTFB((metric) => {
924
1065
  if (!this.webVitalsCollected.ttfb) {
925
1066
  this.webVitalsCollected.ttfb = true;
926
- this.track("web_vital", {
927
- metric: "ttfb",
928
- value: metric.value,
929
- rating: getVitalRating("TTFB", metric.value),
930
- delta: metric.delta,
931
- id: metric.id
932
- });
1067
+ const rating = getVitalRating("TTFB", metric.value);
1068
+ this.sendWebVital(metric, "ttfb", rating);
933
1069
  }
934
1070
  });
935
1071
  if (this.config.debug) {
@@ -975,9 +1111,6 @@ var AureaSDK = class {
975
1111
  window.addEventListener("touchstart", resetInactivityTimer, { passive: true });
976
1112
  window.addEventListener("beforeunload", () => {
977
1113
  const now = Date.now();
978
- if (this.isInCheckout && this.currentStage === "checkout") {
979
- this.checkoutAbandoned("page_close");
980
- }
981
1114
  if (this.isPageVisible) {
982
1115
  this.activeTime += now - this.lastActiveTimestamp;
983
1116
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aurea-tracking-sdk",
3
- "version": "1.3.4",
3
+ "version": "1.5.0",
4
4
  "description": "Standalone tracking SDK for Aurea CRM external funnels",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",