aurea-tracking-sdk 1.0.1 → 1.1.1

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
@@ -33,6 +33,12 @@ declare class AureaSDK {
33
33
  private eventQueue;
34
34
  private batchTimer?;
35
35
  private initialized;
36
+ private sessionStartTime;
37
+ private pageStartTime;
38
+ private activeTime;
39
+ private lastActiveTimestamp;
40
+ private isPageVisible;
41
+ private webVitalsCollected;
36
42
  constructor(config: AureaConfig);
37
43
  /**
38
44
  * Initialize the SDK
@@ -43,7 +49,7 @@ declare class AureaSDK {
43
49
  */
44
50
  track(eventName: string, properties?: Record<string, any>): void;
45
51
  /**
46
- * Identify a user
52
+ * Identify a user (links anonymous user to known user)
47
53
  */
48
54
  identify(userId: string, traits?: Record<string, any>): void;
49
55
  /**
@@ -62,6 +68,10 @@ declare class AureaSDK {
62
68
  * Get or create anonymous ID
63
69
  */
64
70
  private getOrCreateAnonymousId;
71
+ /**
72
+ * Parse device information from user agent
73
+ */
74
+ private parseDeviceInfo;
65
75
  /**
66
76
  * Build event context
67
77
  */
@@ -107,6 +117,14 @@ declare class AureaSDK {
107
117
  * Check if user has completed a purchase
108
118
  */
109
119
  private checkForPurchase;
120
+ /**
121
+ * Track Core Web Vitals
122
+ */
123
+ private trackWebVitals;
124
+ /**
125
+ * Track session timing (active time, duration)
126
+ */
127
+ private trackSessionTiming;
110
128
  /**
111
129
  * Generate unique ID
112
130
  */
package/dist/index.d.ts CHANGED
@@ -33,6 +33,12 @@ declare class AureaSDK {
33
33
  private eventQueue;
34
34
  private batchTimer?;
35
35
  private initialized;
36
+ private sessionStartTime;
37
+ private pageStartTime;
38
+ private activeTime;
39
+ private lastActiveTimestamp;
40
+ private isPageVisible;
41
+ private webVitalsCollected;
36
42
  constructor(config: AureaConfig);
37
43
  /**
38
44
  * Initialize the SDK
@@ -43,7 +49,7 @@ declare class AureaSDK {
43
49
  */
44
50
  track(eventName: string, properties?: Record<string, any>): void;
45
51
  /**
46
- * Identify a user
52
+ * Identify a user (links anonymous user to known user)
47
53
  */
48
54
  identify(userId: string, traits?: Record<string, any>): void;
49
55
  /**
@@ -62,6 +68,10 @@ declare class AureaSDK {
62
68
  * Get or create anonymous ID
63
69
  */
64
70
  private getOrCreateAnonymousId;
71
+ /**
72
+ * Parse device information from user agent
73
+ */
74
+ private parseDeviceInfo;
65
75
  /**
66
76
  * Build event context
67
77
  */
@@ -107,6 +117,14 @@ declare class AureaSDK {
107
117
  * Check if user has completed a purchase
108
118
  */
109
119
  private checkForPurchase;
120
+ /**
121
+ * Track Core Web Vitals
122
+ */
123
+ private trackWebVitals;
124
+ /**
125
+ * Track session timing (active time, duration)
126
+ */
127
+ private trackSessionTiming;
110
128
  /**
111
129
  * Generate unique ID
112
130
  */
package/dist/index.js CHANGED
@@ -27,10 +27,24 @@ __export(index_exports, {
27
27
  trackPage: () => trackPage
28
28
  });
29
29
  module.exports = __toCommonJS(index_exports);
30
+ var import_ua_parser_js = require("ua-parser-js");
31
+ var import_web_vitals = require("web-vitals");
30
32
  var AureaSDK = class {
31
33
  constructor(config) {
32
34
  this.eventQueue = [];
33
35
  this.initialized = false;
36
+ this.sessionStartTime = Date.now();
37
+ this.pageStartTime = Date.now();
38
+ this.activeTime = 0;
39
+ this.lastActiveTimestamp = Date.now();
40
+ this.isPageVisible = true;
41
+ this.webVitalsCollected = {
42
+ lcp: false,
43
+ inp: false,
44
+ cls: false,
45
+ fcp: false,
46
+ ttfb: false
47
+ };
34
48
  this.config = {
35
49
  apiUrl: "http://localhost:3000/api",
36
50
  debug: false,
@@ -82,6 +96,8 @@ var AureaSDK = class {
82
96
  }
83
97
  this.startBatchTimer();
84
98
  this.startPurchasePolling();
99
+ this.trackWebVitals();
100
+ this.trackSessionTiming();
85
101
  if (this.config.debug) {
86
102
  console.log("[Aurea SDK] Initialized", {
87
103
  sessionId: this.sessionId,
@@ -107,9 +123,10 @@ var AureaSDK = class {
107
123
  }
108
124
  }
109
125
  /**
110
- * Identify a user
126
+ * Identify a user (links anonymous user to known user)
111
127
  */
112
128
  identify(userId, traits) {
129
+ const previousUserId = this.userId;
113
130
  this.userId = userId;
114
131
  if (typeof window !== "undefined") {
115
132
  localStorage.setItem("aurea_user_id", userId);
@@ -119,10 +136,17 @@ var AureaSDK = class {
119
136
  }
120
137
  this.track("user_identified", {
121
138
  userId,
122
- traits
139
+ anonymousId: this.anonymousId,
140
+ previousUserId,
141
+ traits: traits || {},
142
+ timestamp: Date.now()
123
143
  });
124
144
  if (this.config.debug) {
125
- console.log("[Aurea SDK] User identified:", userId);
145
+ console.log("[Aurea SDK] User identified:", {
146
+ userId,
147
+ anonymousId: this.anonymousId,
148
+ traits
149
+ });
126
150
  }
127
151
  }
128
152
  /**
@@ -184,6 +208,48 @@ var AureaSDK = class {
184
208
  }
185
209
  return anonymousId;
186
210
  }
211
+ /**
212
+ * Parse device information from user agent
213
+ */
214
+ parseDeviceInfo() {
215
+ if (typeof navigator === "undefined") return void 0;
216
+ const parser = new import_ua_parser_js.UAParser(navigator.userAgent);
217
+ const result = parser.getResult();
218
+ let deviceType = "Desktop";
219
+ if (result.device.type) {
220
+ switch (result.device.type.toLowerCase()) {
221
+ case "mobile":
222
+ deviceType = "Mobile";
223
+ break;
224
+ case "tablet":
225
+ deviceType = "Tablet";
226
+ break;
227
+ case "smarttv":
228
+ deviceType = "Smart TV";
229
+ break;
230
+ case "wearable":
231
+ deviceType = "Wearable";
232
+ break;
233
+ case "console":
234
+ deviceType = "Console";
235
+ break;
236
+ default:
237
+ deviceType = "Desktop";
238
+ }
239
+ }
240
+ return {
241
+ userAgent: navigator.userAgent,
242
+ deviceType,
243
+ browserName: result.browser.name || "Unknown",
244
+ browserVersion: result.browser.version || "Unknown",
245
+ osName: result.os.name || "Unknown",
246
+ osVersion: result.os.version || "Unknown",
247
+ screenWidth: window.screen?.width,
248
+ screenHeight: window.screen?.height,
249
+ language: navigator.language,
250
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
251
+ };
252
+ }
187
253
  /**
188
254
  * Build event context
189
255
  */
@@ -210,13 +276,7 @@ var AureaSDK = class {
210
276
  session: {
211
277
  sessionId: this.sessionId
212
278
  },
213
- device: typeof navigator !== "undefined" ? {
214
- userAgent: navigator.userAgent,
215
- screenWidth: window.screen?.width,
216
- screenHeight: window.screen?.height,
217
- language: navigator.language,
218
- timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
219
- } : void 0
279
+ device: typeof navigator !== "undefined" ? this.parseDeviceInfo() : void 0
220
280
  };
221
281
  }
222
282
  /**
@@ -400,6 +460,144 @@ var AureaSDK = class {
400
460
  }
401
461
  }
402
462
  }
463
+ /**
464
+ * Track Core Web Vitals
465
+ */
466
+ trackWebVitals() {
467
+ if (typeof window === "undefined") return;
468
+ const getVitalRating = (name, value) => {
469
+ const thresholds = {
470
+ LCP: [2500, 4e3],
471
+ INP: [200, 500],
472
+ CLS: [0.1, 0.25],
473
+ FCP: [1800, 3e3],
474
+ TTFB: [800, 1800]
475
+ };
476
+ const [good, needsImprovement] = thresholds[name] || [0, 0];
477
+ if (value <= good) return "good";
478
+ if (value <= needsImprovement) return "needs-improvement";
479
+ return "poor";
480
+ };
481
+ (0, import_web_vitals.onLCP)((metric) => {
482
+ if (!this.webVitalsCollected.lcp) {
483
+ this.webVitalsCollected.lcp = true;
484
+ this.track("web_vital", {
485
+ metric: "lcp",
486
+ value: metric.value,
487
+ rating: getVitalRating("LCP", metric.value),
488
+ delta: metric.delta,
489
+ id: metric.id
490
+ });
491
+ }
492
+ });
493
+ (0, import_web_vitals.onINP)((metric) => {
494
+ if (!this.webVitalsCollected.inp) {
495
+ this.webVitalsCollected.inp = true;
496
+ this.track("web_vital", {
497
+ metric: "inp",
498
+ value: metric.value,
499
+ rating: getVitalRating("INP", metric.value),
500
+ delta: metric.delta,
501
+ id: metric.id
502
+ });
503
+ }
504
+ });
505
+ (0, import_web_vitals.onCLS)((metric) => {
506
+ if (!this.webVitalsCollected.cls) {
507
+ this.webVitalsCollected.cls = true;
508
+ this.track("web_vital", {
509
+ metric: "cls",
510
+ value: metric.value,
511
+ rating: getVitalRating("CLS", metric.value),
512
+ delta: metric.delta,
513
+ id: metric.id
514
+ });
515
+ }
516
+ });
517
+ (0, import_web_vitals.onFCP)((metric) => {
518
+ if (!this.webVitalsCollected.fcp) {
519
+ this.webVitalsCollected.fcp = true;
520
+ this.track("web_vital", {
521
+ metric: "fcp",
522
+ value: metric.value,
523
+ rating: getVitalRating("FCP", metric.value),
524
+ delta: metric.delta,
525
+ id: metric.id
526
+ });
527
+ }
528
+ });
529
+ (0, import_web_vitals.onTTFB)((metric) => {
530
+ if (!this.webVitalsCollected.ttfb) {
531
+ this.webVitalsCollected.ttfb = true;
532
+ this.track("web_vital", {
533
+ metric: "ttfb",
534
+ value: metric.value,
535
+ rating: getVitalRating("TTFB", metric.value),
536
+ delta: metric.delta,
537
+ id: metric.id
538
+ });
539
+ }
540
+ });
541
+ if (this.config.debug) {
542
+ console.log("[Aurea SDK] Core Web Vitals tracking enabled");
543
+ }
544
+ }
545
+ /**
546
+ * Track session timing (active time, duration)
547
+ */
548
+ trackSessionTiming() {
549
+ if (typeof window === "undefined") return;
550
+ document.addEventListener("visibilitychange", () => {
551
+ const now = Date.now();
552
+ if (document.hidden) {
553
+ if (this.isPageVisible) {
554
+ this.activeTime += now - this.lastActiveTimestamp;
555
+ this.isPageVisible = false;
556
+ }
557
+ } else {
558
+ this.isPageVisible = true;
559
+ this.lastActiveTimestamp = now;
560
+ }
561
+ });
562
+ let interactionTimeout;
563
+ const resetInactivityTimer = () => {
564
+ const now = Date.now();
565
+ if (!this.isPageVisible) {
566
+ this.isPageVisible = true;
567
+ this.lastActiveTimestamp = now;
568
+ }
569
+ clearTimeout(interactionTimeout);
570
+ interactionTimeout = setTimeout(() => {
571
+ if (this.isPageVisible) {
572
+ this.activeTime += Date.now() - this.lastActiveTimestamp;
573
+ this.isPageVisible = false;
574
+ }
575
+ }, 3e4);
576
+ };
577
+ window.addEventListener("mousemove", resetInactivityTimer, { passive: true });
578
+ window.addEventListener("keydown", resetInactivityTimer, { passive: true });
579
+ window.addEventListener("scroll", resetInactivityTimer, { passive: true });
580
+ window.addEventListener("click", resetInactivityTimer, { passive: true });
581
+ window.addEventListener("touchstart", resetInactivityTimer, { passive: true });
582
+ window.addEventListener("beforeunload", () => {
583
+ const now = Date.now();
584
+ if (this.isPageVisible) {
585
+ this.activeTime += now - this.lastActiveTimestamp;
586
+ }
587
+ const totalDuration = Math.floor((now - this.sessionStartTime) / 1e3);
588
+ const activeTimeSeconds = Math.floor(this.activeTime / 1e3);
589
+ this.track("session_end", {
590
+ duration: totalDuration,
591
+ activeTime: activeTimeSeconds,
592
+ idleTime: totalDuration - activeTimeSeconds,
593
+ engagementRate: totalDuration > 0 ? activeTimeSeconds / totalDuration * 100 : 0
594
+ });
595
+ this.flushEvents();
596
+ });
597
+ if (this.config.debug) {
598
+ console.log("[Aurea SDK] Session timing tracking enabled");
599
+ }
600
+ }
403
601
  /**
404
602
  * Generate unique ID
405
603
  */
package/dist/index.mjs CHANGED
@@ -1,8 +1,22 @@
1
1
  // src/index.ts
2
+ import { UAParser } from "ua-parser-js";
3
+ import { onLCP, onINP, onCLS, onFCP, onTTFB } from "web-vitals";
2
4
  var AureaSDK = class {
3
5
  constructor(config) {
4
6
  this.eventQueue = [];
5
7
  this.initialized = false;
8
+ this.sessionStartTime = Date.now();
9
+ this.pageStartTime = Date.now();
10
+ this.activeTime = 0;
11
+ this.lastActiveTimestamp = Date.now();
12
+ this.isPageVisible = true;
13
+ this.webVitalsCollected = {
14
+ lcp: false,
15
+ inp: false,
16
+ cls: false,
17
+ fcp: false,
18
+ ttfb: false
19
+ };
6
20
  this.config = {
7
21
  apiUrl: "http://localhost:3000/api",
8
22
  debug: false,
@@ -54,6 +68,8 @@ var AureaSDK = class {
54
68
  }
55
69
  this.startBatchTimer();
56
70
  this.startPurchasePolling();
71
+ this.trackWebVitals();
72
+ this.trackSessionTiming();
57
73
  if (this.config.debug) {
58
74
  console.log("[Aurea SDK] Initialized", {
59
75
  sessionId: this.sessionId,
@@ -79,9 +95,10 @@ var AureaSDK = class {
79
95
  }
80
96
  }
81
97
  /**
82
- * Identify a user
98
+ * Identify a user (links anonymous user to known user)
83
99
  */
84
100
  identify(userId, traits) {
101
+ const previousUserId = this.userId;
85
102
  this.userId = userId;
86
103
  if (typeof window !== "undefined") {
87
104
  localStorage.setItem("aurea_user_id", userId);
@@ -91,10 +108,17 @@ var AureaSDK = class {
91
108
  }
92
109
  this.track("user_identified", {
93
110
  userId,
94
- traits
111
+ anonymousId: this.anonymousId,
112
+ previousUserId,
113
+ traits: traits || {},
114
+ timestamp: Date.now()
95
115
  });
96
116
  if (this.config.debug) {
97
- console.log("[Aurea SDK] User identified:", userId);
117
+ console.log("[Aurea SDK] User identified:", {
118
+ userId,
119
+ anonymousId: this.anonymousId,
120
+ traits
121
+ });
98
122
  }
99
123
  }
100
124
  /**
@@ -156,6 +180,48 @@ var AureaSDK = class {
156
180
  }
157
181
  return anonymousId;
158
182
  }
183
+ /**
184
+ * Parse device information from user agent
185
+ */
186
+ parseDeviceInfo() {
187
+ if (typeof navigator === "undefined") return void 0;
188
+ const parser = new UAParser(navigator.userAgent);
189
+ const result = parser.getResult();
190
+ let deviceType = "Desktop";
191
+ if (result.device.type) {
192
+ switch (result.device.type.toLowerCase()) {
193
+ case "mobile":
194
+ deviceType = "Mobile";
195
+ break;
196
+ case "tablet":
197
+ deviceType = "Tablet";
198
+ break;
199
+ case "smarttv":
200
+ deviceType = "Smart TV";
201
+ break;
202
+ case "wearable":
203
+ deviceType = "Wearable";
204
+ break;
205
+ case "console":
206
+ deviceType = "Console";
207
+ break;
208
+ default:
209
+ deviceType = "Desktop";
210
+ }
211
+ }
212
+ return {
213
+ userAgent: navigator.userAgent,
214
+ deviceType,
215
+ browserName: result.browser.name || "Unknown",
216
+ browserVersion: result.browser.version || "Unknown",
217
+ osName: result.os.name || "Unknown",
218
+ osVersion: result.os.version || "Unknown",
219
+ screenWidth: window.screen?.width,
220
+ screenHeight: window.screen?.height,
221
+ language: navigator.language,
222
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
223
+ };
224
+ }
159
225
  /**
160
226
  * Build event context
161
227
  */
@@ -182,13 +248,7 @@ var AureaSDK = class {
182
248
  session: {
183
249
  sessionId: this.sessionId
184
250
  },
185
- device: typeof navigator !== "undefined" ? {
186
- userAgent: navigator.userAgent,
187
- screenWidth: window.screen?.width,
188
- screenHeight: window.screen?.height,
189
- language: navigator.language,
190
- timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
191
- } : void 0
251
+ device: typeof navigator !== "undefined" ? this.parseDeviceInfo() : void 0
192
252
  };
193
253
  }
194
254
  /**
@@ -372,6 +432,144 @@ var AureaSDK = class {
372
432
  }
373
433
  }
374
434
  }
435
+ /**
436
+ * Track Core Web Vitals
437
+ */
438
+ trackWebVitals() {
439
+ if (typeof window === "undefined") return;
440
+ const getVitalRating = (name, value) => {
441
+ const thresholds = {
442
+ LCP: [2500, 4e3],
443
+ INP: [200, 500],
444
+ CLS: [0.1, 0.25],
445
+ FCP: [1800, 3e3],
446
+ TTFB: [800, 1800]
447
+ };
448
+ const [good, needsImprovement] = thresholds[name] || [0, 0];
449
+ if (value <= good) return "good";
450
+ if (value <= needsImprovement) return "needs-improvement";
451
+ return "poor";
452
+ };
453
+ onLCP((metric) => {
454
+ if (!this.webVitalsCollected.lcp) {
455
+ this.webVitalsCollected.lcp = true;
456
+ this.track("web_vital", {
457
+ metric: "lcp",
458
+ value: metric.value,
459
+ rating: getVitalRating("LCP", metric.value),
460
+ delta: metric.delta,
461
+ id: metric.id
462
+ });
463
+ }
464
+ });
465
+ onINP((metric) => {
466
+ if (!this.webVitalsCollected.inp) {
467
+ this.webVitalsCollected.inp = true;
468
+ this.track("web_vital", {
469
+ metric: "inp",
470
+ value: metric.value,
471
+ rating: getVitalRating("INP", metric.value),
472
+ delta: metric.delta,
473
+ id: metric.id
474
+ });
475
+ }
476
+ });
477
+ onCLS((metric) => {
478
+ if (!this.webVitalsCollected.cls) {
479
+ this.webVitalsCollected.cls = true;
480
+ this.track("web_vital", {
481
+ metric: "cls",
482
+ value: metric.value,
483
+ rating: getVitalRating("CLS", metric.value),
484
+ delta: metric.delta,
485
+ id: metric.id
486
+ });
487
+ }
488
+ });
489
+ onFCP((metric) => {
490
+ if (!this.webVitalsCollected.fcp) {
491
+ this.webVitalsCollected.fcp = true;
492
+ this.track("web_vital", {
493
+ metric: "fcp",
494
+ value: metric.value,
495
+ rating: getVitalRating("FCP", metric.value),
496
+ delta: metric.delta,
497
+ id: metric.id
498
+ });
499
+ }
500
+ });
501
+ onTTFB((metric) => {
502
+ if (!this.webVitalsCollected.ttfb) {
503
+ this.webVitalsCollected.ttfb = true;
504
+ this.track("web_vital", {
505
+ metric: "ttfb",
506
+ value: metric.value,
507
+ rating: getVitalRating("TTFB", metric.value),
508
+ delta: metric.delta,
509
+ id: metric.id
510
+ });
511
+ }
512
+ });
513
+ if (this.config.debug) {
514
+ console.log("[Aurea SDK] Core Web Vitals tracking enabled");
515
+ }
516
+ }
517
+ /**
518
+ * Track session timing (active time, duration)
519
+ */
520
+ trackSessionTiming() {
521
+ if (typeof window === "undefined") return;
522
+ document.addEventListener("visibilitychange", () => {
523
+ const now = Date.now();
524
+ if (document.hidden) {
525
+ if (this.isPageVisible) {
526
+ this.activeTime += now - this.lastActiveTimestamp;
527
+ this.isPageVisible = false;
528
+ }
529
+ } else {
530
+ this.isPageVisible = true;
531
+ this.lastActiveTimestamp = now;
532
+ }
533
+ });
534
+ let interactionTimeout;
535
+ const resetInactivityTimer = () => {
536
+ const now = Date.now();
537
+ if (!this.isPageVisible) {
538
+ this.isPageVisible = true;
539
+ this.lastActiveTimestamp = now;
540
+ }
541
+ clearTimeout(interactionTimeout);
542
+ interactionTimeout = setTimeout(() => {
543
+ if (this.isPageVisible) {
544
+ this.activeTime += Date.now() - this.lastActiveTimestamp;
545
+ this.isPageVisible = false;
546
+ }
547
+ }, 3e4);
548
+ };
549
+ window.addEventListener("mousemove", resetInactivityTimer, { passive: true });
550
+ window.addEventListener("keydown", resetInactivityTimer, { passive: true });
551
+ window.addEventListener("scroll", resetInactivityTimer, { passive: true });
552
+ window.addEventListener("click", resetInactivityTimer, { passive: true });
553
+ window.addEventListener("touchstart", resetInactivityTimer, { passive: true });
554
+ window.addEventListener("beforeunload", () => {
555
+ const now = Date.now();
556
+ if (this.isPageVisible) {
557
+ this.activeTime += now - this.lastActiveTimestamp;
558
+ }
559
+ const totalDuration = Math.floor((now - this.sessionStartTime) / 1e3);
560
+ const activeTimeSeconds = Math.floor(this.activeTime / 1e3);
561
+ this.track("session_end", {
562
+ duration: totalDuration,
563
+ activeTime: activeTimeSeconds,
564
+ idleTime: totalDuration - activeTimeSeconds,
565
+ engagementRate: totalDuration > 0 ? activeTimeSeconds / totalDuration * 100 : 0
566
+ });
567
+ this.flushEvents();
568
+ });
569
+ if (this.config.debug) {
570
+ console.log("[Aurea SDK] Session timing tracking enabled");
571
+ }
572
+ }
375
573
  /**
376
574
  * Generate unique ID
377
575
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aurea-tracking-sdk",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "Standalone tracking SDK for Aurea CRM external funnels",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -26,15 +26,19 @@
26
26
  "license": "MIT",
27
27
  "repository": {
28
28
  "type": "git",
29
- "url": "https://github.com/yourusername/aurea-tracking-sdk.git"
29
+ "url": "git+https://github.com/akal0/aurea-tracking-sdk.git"
30
30
  },
31
31
  "bugs": {
32
- "url": "https://github.com/yourusername/aurea-tracking-sdk/issues"
32
+ "url": "https://github.com/akal0/aurea-tracking-sdk/issues"
33
33
  },
34
- "homepage": "https://github.com/yourusername/aurea-tracking-sdk#readme",
34
+ "homepage": "https://github.com/akal0/aurea-tracking-sdk#readme",
35
35
  "devDependencies": {
36
36
  "@types/node": "^25.0.3",
37
37
  "tsup": "^8.0.1",
38
38
  "typescript": "^5.3.3"
39
+ },
40
+ "dependencies": {
41
+ "ua-parser-js": "^2.0.7",
42
+ "web-vitals": "^5.1.0"
39
43
  }
40
44
  }