@datalyr/web 1.0.6 → 1.1.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/datalyr.cjs.js +124 -224
- package/dist/datalyr.cjs.js.map +1 -1
- package/dist/datalyr.esm.js +124 -224
- package/dist/datalyr.esm.js.map +1 -1
- package/dist/datalyr.esm.min.js +1 -1
- package/dist/datalyr.esm.min.js.map +1 -1
- package/dist/datalyr.js +124 -224
- package/dist/datalyr.js.map +1 -1
- package/dist/datalyr.min.js +1 -1
- package/dist/datalyr.min.js.map +1 -1
- package/dist/fingerprint.d.ts +6 -39
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/identity.d.ts +4 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/types.d.ts +11 -27
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/datalyr.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @datalyr/web v1.0
|
|
2
|
+
* @datalyr/web v1.1.0
|
|
3
3
|
* Datalyr Web SDK - Modern attribution tracking for web applications
|
|
4
4
|
* (c) 2025 Datalyr Inc.
|
|
5
5
|
* Released under the MIT License
|
|
@@ -161,7 +161,16 @@ class CookieStorage {
|
|
|
161
161
|
const value = `; ${document.cookie}`;
|
|
162
162
|
const parts = value.split(`; ${name}=`);
|
|
163
163
|
if (parts.length === 2) {
|
|
164
|
-
|
|
164
|
+
const rawValue = ((_a = parts.pop()) === null || _a === void 0 ? void 0 : _a.split(';').shift()) || null;
|
|
165
|
+
if (rawValue) {
|
|
166
|
+
try {
|
|
167
|
+
return decodeURIComponent(rawValue);
|
|
168
|
+
}
|
|
169
|
+
catch (_b) {
|
|
170
|
+
// Return raw value if decoding fails (backwards compatibility)
|
|
171
|
+
return rawValue;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
165
174
|
}
|
|
166
175
|
return null;
|
|
167
176
|
}
|
|
@@ -395,6 +404,33 @@ function isGlobalPrivacyControlEnabled() {
|
|
|
395
404
|
return navigator.globalPrivacyControl === true ||
|
|
396
405
|
window.globalPrivacyControl === true;
|
|
397
406
|
}
|
|
407
|
+
/**
|
|
408
|
+
* Get root domain for cross-subdomain tracking
|
|
409
|
+
*/
|
|
410
|
+
function getRootDomain() {
|
|
411
|
+
const hostname = window.location.hostname;
|
|
412
|
+
// Handle localhost and IP addresses
|
|
413
|
+
if (hostname === 'localhost' ||
|
|
414
|
+
hostname.match(/^[0-9]{1,3}\./) || // IPv4
|
|
415
|
+
hostname.match(/^\[?[0-9a-fA-F:]+\]?$/)) { // IPv6
|
|
416
|
+
return hostname;
|
|
417
|
+
}
|
|
418
|
+
// Get root domain (last two parts: example.com)
|
|
419
|
+
const parts = hostname.split('.');
|
|
420
|
+
if (parts.length >= 2) {
|
|
421
|
+
// Handle .co.uk, .com.au, etc
|
|
422
|
+
const tld = parts[parts.length - 1];
|
|
423
|
+
const sld = parts[parts.length - 2];
|
|
424
|
+
// Common two-part TLDs
|
|
425
|
+
const twoPartTlds = ['co.uk', 'com.au', 'co.nz', 'co.jp', 'co.in', 'co.za'];
|
|
426
|
+
const lastTwo = `${sld}.${tld}`;
|
|
427
|
+
if (twoPartTlds.includes(lastTwo) && parts.length >= 3) {
|
|
428
|
+
return '.' + parts.slice(-3).join('.');
|
|
429
|
+
}
|
|
430
|
+
return '.' + parts.slice(-2).join('.');
|
|
431
|
+
}
|
|
432
|
+
return hostname;
|
|
433
|
+
}
|
|
398
434
|
/**
|
|
399
435
|
* Get referrer data
|
|
400
436
|
*/
|
|
@@ -458,13 +494,61 @@ class IdentityManager {
|
|
|
458
494
|
* Get or create anonymous ID (device/browser identifier)
|
|
459
495
|
*/
|
|
460
496
|
getOrCreateAnonymousId() {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
497
|
+
// 1. Check root domain cookie first (works across subdomains)
|
|
498
|
+
let anonymousId = cookies.get('__dl_visitor_id');
|
|
499
|
+
if (anonymousId) {
|
|
500
|
+
// Found in cookie - sync to localStorage
|
|
464
501
|
storage.set('dl_anonymous_id', anonymousId);
|
|
465
|
-
|
|
502
|
+
return anonymousId;
|
|
503
|
+
}
|
|
504
|
+
// 2. Check localStorage (fallback for cookie issues)
|
|
505
|
+
anonymousId = storage.get('dl_anonymous_id');
|
|
506
|
+
if (anonymousId) {
|
|
507
|
+
// Found in localStorage - set root domain cookie
|
|
508
|
+
this.setRootDomainCookie('__dl_visitor_id', anonymousId);
|
|
509
|
+
return anonymousId;
|
|
510
|
+
}
|
|
511
|
+
// 3. Generate new ID
|
|
512
|
+
anonymousId = `anon_${generateUUID()}`;
|
|
513
|
+
// 4. Store in both cookie (primary) and localStorage (backup)
|
|
514
|
+
this.setRootDomainCookie('__dl_visitor_id', anonymousId);
|
|
515
|
+
storage.set('dl_anonymous_id', anonymousId);
|
|
466
516
|
return anonymousId;
|
|
467
517
|
}
|
|
518
|
+
/**
|
|
519
|
+
* Set a root domain cookie for cross-subdomain tracking
|
|
520
|
+
*/
|
|
521
|
+
setRootDomainCookie(name, value) {
|
|
522
|
+
try {
|
|
523
|
+
const rootDomain = getRootDomain();
|
|
524
|
+
const secure = location.protocol === 'https:' ? '; Secure' : '';
|
|
525
|
+
const encodedValue = encodeURIComponent(value);
|
|
526
|
+
// Set cookie with root domain, 1 year expiry
|
|
527
|
+
document.cookie = `${name}=${encodedValue}; domain=${rootDomain}; path=/; max-age=31536000; SameSite=Lax${secure}`;
|
|
528
|
+
// Verify cookie was set successfully (cookies.get already decodes)
|
|
529
|
+
const verifyValue = cookies.get(name);
|
|
530
|
+
if (verifyValue === value) {
|
|
531
|
+
console.log(`[Datalyr] Set root domain cookie: ${name} on domain: ${rootDomain}`);
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
// Fallback: try without domain (current subdomain only)
|
|
535
|
+
document.cookie = `${name}=${encodedValue}; path=/; max-age=31536000; SameSite=Lax${secure}`;
|
|
536
|
+
console.log(`[Datalyr] Set cookie without domain (fallback): ${name}`);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
catch (e) {
|
|
540
|
+
console.error('[Datalyr] Error setting root domain cookie:', e);
|
|
541
|
+
// Still try to set without domain as fallback
|
|
542
|
+
try {
|
|
543
|
+
const secure = location.protocol === 'https:' ? '; Secure' : '';
|
|
544
|
+
const encodedValue = encodeURIComponent(value);
|
|
545
|
+
document.cookie = `${name}=${encodedValue}; path=/; max-age=31536000; SameSite=Lax${secure}`;
|
|
546
|
+
}
|
|
547
|
+
catch (fallbackError) {
|
|
548
|
+
console.error('[Datalyr] Failed to set cookie even without domain:', fallbackError);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
468
552
|
/**
|
|
469
553
|
* Get stored user ID from previous session
|
|
470
554
|
*/
|
|
@@ -558,6 +642,8 @@ class IdentityManager {
|
|
|
558
642
|
// Generate new anonymous ID for privacy
|
|
559
643
|
this.anonymousId = `anon_${generateUUID()}`;
|
|
560
644
|
storage.set('dl_anonymous_id', this.anonymousId);
|
|
645
|
+
// Update root domain cookie with new ID
|
|
646
|
+
this.setRootDomainCookie('__dl_visitor_id', this.anonymousId);
|
|
561
647
|
}
|
|
562
648
|
/**
|
|
563
649
|
* Get all identity fields for event payload
|
|
@@ -1537,24 +1623,40 @@ class FingerprintCollector {
|
|
|
1537
1623
|
}
|
|
1538
1624
|
/**
|
|
1539
1625
|
* Collect minimal fingerprint data (privacy-friendly)
|
|
1626
|
+
* Matches browser tag minimal fingerprinting approach
|
|
1540
1627
|
*/
|
|
1541
1628
|
collectMinimal() {
|
|
1542
|
-
|
|
1629
|
+
const fp = {
|
|
1543
1630
|
timezone: this.getTimezone(),
|
|
1544
1631
|
language: navigator.language || null,
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
sessionStorageAvailable: this.testStorage('sessionStorage')
|
|
1632
|
+
screen_bucket: this.getScreenBucket(),
|
|
1633
|
+
dnt: (navigator.doNotTrack === '1' || window.globalPrivacyControl === true) || null,
|
|
1634
|
+
userAgent: navigator.userAgent || null
|
|
1549
1635
|
};
|
|
1636
|
+
// User-Agent Client Hints (modern browsers)
|
|
1637
|
+
if ('userAgentData' in navigator) {
|
|
1638
|
+
const uaData = navigator.userAgentData;
|
|
1639
|
+
fp.userAgentData = {
|
|
1640
|
+
brands: uaData.brands || [],
|
|
1641
|
+
mobile: uaData.mobile || false,
|
|
1642
|
+
platform: uaData.platform || null
|
|
1643
|
+
};
|
|
1644
|
+
}
|
|
1645
|
+
return fp;
|
|
1550
1646
|
}
|
|
1551
1647
|
/**
|
|
1552
1648
|
* Collect standard fingerprint data
|
|
1649
|
+
* PRIVACY: Minimal data collection matching browser tag approach
|
|
1650
|
+
* Only collects data necessary for basic analytics and attribution
|
|
1553
1651
|
*/
|
|
1554
1652
|
collectStandard() {
|
|
1555
1653
|
const fingerprint = {};
|
|
1556
1654
|
try {
|
|
1557
|
-
//
|
|
1655
|
+
// PRIVACY: Only collect minimal data needed for attribution
|
|
1656
|
+
fingerprint.timezone = this.getTimezone();
|
|
1657
|
+
fingerprint.language = navigator.language || null;
|
|
1658
|
+
fingerprint.screen_bucket = this.getScreenBucket();
|
|
1659
|
+
fingerprint.dnt = (navigator.doNotTrack === '1' || window.globalPrivacyControl === true) || null;
|
|
1558
1660
|
fingerprint.userAgent = navigator.userAgent || null;
|
|
1559
1661
|
// User-Agent Client Hints (modern browsers)
|
|
1560
1662
|
if ('userAgentData' in navigator) {
|
|
@@ -1565,125 +1667,14 @@ class FingerprintCollector {
|
|
|
1565
1667
|
platform: uaData.platform || null
|
|
1566
1668
|
};
|
|
1567
1669
|
}
|
|
1568
|
-
// Language settings
|
|
1569
|
-
fingerprint.language = navigator.language || null;
|
|
1570
|
-
fingerprint.languages = navigator.languages ?
|
|
1571
|
-
navigator.languages.slice(0, 2) : null; // Limit to 2 for privacy
|
|
1572
|
-
// Platform and browser features
|
|
1573
|
-
fingerprint.platform = navigator.platform || null;
|
|
1574
|
-
fingerprint.cookieEnabled = navigator.cookieEnabled || null;
|
|
1575
|
-
fingerprint.doNotTrack = navigator.doNotTrack || null;
|
|
1576
|
-
// Hardware (coarsened for privacy)
|
|
1577
|
-
fingerprint.hardwareConcurrency = this.coarsenHardwareConcurrency();
|
|
1578
|
-
fingerprint.deviceMemory = this.coarsenDeviceMemory();
|
|
1579
|
-
fingerprint.maxTouchPoints = navigator.maxTouchPoints > 0 ? 'touch' : 'no-touch';
|
|
1580
|
-
// Screen (coarsened)
|
|
1581
|
-
fingerprint.screenResolution = this.getScreenResolution();
|
|
1582
|
-
fingerprint.colorDepth = screen.colorDepth || null;
|
|
1583
|
-
fingerprint.pixelRatio = this.coarsenPixelRatio();
|
|
1584
|
-
// Timezone
|
|
1585
|
-
fingerprint.timezone = this.getTimezone();
|
|
1586
|
-
fingerprint.timezoneOffset = this.coarsenTimezoneOffset();
|
|
1587
|
-
// Canvas fingerprinting disabled for privacy
|
|
1588
|
-
fingerprint.canvasEnabled = false;
|
|
1589
|
-
// Plugins count only (not details for privacy)
|
|
1590
|
-
fingerprint.pluginsCount = navigator.plugins ? navigator.plugins.length : null;
|
|
1591
|
-
// Storage availability
|
|
1592
|
-
fingerprint.localStorageAvailable = this.testStorage('localStorage');
|
|
1593
|
-
fingerprint.sessionStorageAvailable = this.testStorage('sessionStorage');
|
|
1594
|
-
fingerprint.indexedDBAvailable = this.testIndexedDB();
|
|
1595
|
-
// Add cached heavy fingerprint data if available
|
|
1596
|
-
if (this.heavyFingerprintDone) {
|
|
1597
|
-
Object.assign(fingerprint, this.fingerprintCache);
|
|
1598
|
-
}
|
|
1599
1670
|
}
|
|
1600
1671
|
catch (e) {
|
|
1601
1672
|
console.warn('[Datalyr] Error collecting fingerprint:', e);
|
|
1602
1673
|
}
|
|
1603
1674
|
return fingerprint;
|
|
1604
1675
|
}
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
* Called lazily on first event to improve page load performance
|
|
1608
|
-
*/
|
|
1609
|
-
collectHeavyFingerprint() {
|
|
1610
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1611
|
-
if (this.heavyFingerprintDone || this.privacyMode === 'strict') {
|
|
1612
|
-
return;
|
|
1613
|
-
}
|
|
1614
|
-
try {
|
|
1615
|
-
// WebGL fingerprinting
|
|
1616
|
-
const webglData = this.getWebGLFingerprint();
|
|
1617
|
-
if (webglData) {
|
|
1618
|
-
this.fingerprintCache.webglVendor = webglData.vendor;
|
|
1619
|
-
this.fingerprintCache.webglRenderer = webglData.renderer;
|
|
1620
|
-
}
|
|
1621
|
-
// Audio fingerprinting
|
|
1622
|
-
const audioData = yield this.getAudioFingerprint();
|
|
1623
|
-
if (audioData) {
|
|
1624
|
-
this.fingerprintCache.audioSampleRate = audioData.sampleRate;
|
|
1625
|
-
this.fingerprintCache.audioState = audioData.state;
|
|
1626
|
-
this.fingerprintCache.audioMaxChannels = audioData.maxChannels;
|
|
1627
|
-
}
|
|
1628
|
-
this.heavyFingerprintDone = true;
|
|
1629
|
-
}
|
|
1630
|
-
catch (e) {
|
|
1631
|
-
console.warn('[Datalyr] Heavy fingerprinting failed:', e);
|
|
1632
|
-
}
|
|
1633
|
-
});
|
|
1634
|
-
}
|
|
1635
|
-
/**
|
|
1636
|
-
* Get WebGL fingerprint
|
|
1637
|
-
*/
|
|
1638
|
-
getWebGLFingerprint() {
|
|
1639
|
-
try {
|
|
1640
|
-
const canvas = document.createElement('canvas');
|
|
1641
|
-
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
|
|
1642
|
-
if (!gl)
|
|
1643
|
-
return null;
|
|
1644
|
-
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
|
|
1645
|
-
if (!debugInfo) {
|
|
1646
|
-
return {
|
|
1647
|
-
vendor: gl.getParameter(gl.VENDOR) || 'unknown',
|
|
1648
|
-
renderer: gl.getParameter(gl.RENDERER) || 'unknown'
|
|
1649
|
-
};
|
|
1650
|
-
}
|
|
1651
|
-
return {
|
|
1652
|
-
vendor: gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) || 'unknown',
|
|
1653
|
-
renderer: gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) || 'unknown'
|
|
1654
|
-
};
|
|
1655
|
-
}
|
|
1656
|
-
catch (_a) {
|
|
1657
|
-
return null;
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
/**
|
|
1661
|
-
* Get audio fingerprint
|
|
1662
|
-
*/
|
|
1663
|
-
getAudioFingerprint() {
|
|
1664
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1665
|
-
var _a;
|
|
1666
|
-
try {
|
|
1667
|
-
const AudioContext = window.AudioContext || window.webkitAudioContext;
|
|
1668
|
-
if (!AudioContext)
|
|
1669
|
-
return null;
|
|
1670
|
-
const audioCtx = new AudioContext();
|
|
1671
|
-
const result = {
|
|
1672
|
-
sampleRate: audioCtx.sampleRate || null,
|
|
1673
|
-
state: audioCtx.state || null,
|
|
1674
|
-
maxChannels: ((_a = audioCtx.destination) === null || _a === void 0 ? void 0 : _a.maxChannelCount) || null
|
|
1675
|
-
};
|
|
1676
|
-
// Close context to free resources
|
|
1677
|
-
if (audioCtx.close) {
|
|
1678
|
-
yield audioCtx.close();
|
|
1679
|
-
}
|
|
1680
|
-
return result;
|
|
1681
|
-
}
|
|
1682
|
-
catch (_b) {
|
|
1683
|
-
return null;
|
|
1684
|
-
}
|
|
1685
|
-
});
|
|
1686
|
-
}
|
|
1676
|
+
// PRIVACY: Heavy fingerprinting (WebGL, Audio) removed
|
|
1677
|
+
// Minimal fingerprinting only for privacy compliance
|
|
1687
1678
|
/**
|
|
1688
1679
|
* Get timezone
|
|
1689
1680
|
*/
|
|
@@ -1696,10 +1687,13 @@ class FingerprintCollector {
|
|
|
1696
1687
|
}
|
|
1697
1688
|
}
|
|
1698
1689
|
/**
|
|
1699
|
-
* Get screen
|
|
1690
|
+
* Get coarse screen bucket for basic device classification
|
|
1691
|
+
* Rounds to nearest 100px for privacy
|
|
1700
1692
|
*/
|
|
1701
|
-
|
|
1693
|
+
getScreenBucket() {
|
|
1702
1694
|
try {
|
|
1695
|
+
if (!window.screen)
|
|
1696
|
+
return null;
|
|
1703
1697
|
const width = Math.round(screen.width / 100) * 100;
|
|
1704
1698
|
const height = Math.round(screen.height / 100) * 100;
|
|
1705
1699
|
return `${width}x${height}`;
|
|
@@ -1708,96 +1702,8 @@ class FingerprintCollector {
|
|
|
1708
1702
|
return null;
|
|
1709
1703
|
}
|
|
1710
1704
|
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
*/
|
|
1714
|
-
coarsenHardwareConcurrency() {
|
|
1715
|
-
try {
|
|
1716
|
-
const cores = navigator.hardwareConcurrency;
|
|
1717
|
-
if (!cores)
|
|
1718
|
-
return null;
|
|
1719
|
-
return cores > 8 ? '8+' : cores;
|
|
1720
|
-
}
|
|
1721
|
-
catch (_a) {
|
|
1722
|
-
return null;
|
|
1723
|
-
}
|
|
1724
|
-
}
|
|
1725
|
-
/**
|
|
1726
|
-
* Coarsen device memory for privacy
|
|
1727
|
-
*/
|
|
1728
|
-
coarsenDeviceMemory() {
|
|
1729
|
-
try {
|
|
1730
|
-
const memory = navigator.deviceMemory;
|
|
1731
|
-
if (!memory)
|
|
1732
|
-
return null;
|
|
1733
|
-
return memory > 4 ? '4+' : memory;
|
|
1734
|
-
}
|
|
1735
|
-
catch (_a) {
|
|
1736
|
-
return null;
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1739
|
-
/**
|
|
1740
|
-
* Coarsen pixel ratio for privacy
|
|
1741
|
-
*/
|
|
1742
|
-
coarsenPixelRatio() {
|
|
1743
|
-
try {
|
|
1744
|
-
const ratio = window.devicePixelRatio;
|
|
1745
|
-
if (!ratio)
|
|
1746
|
-
return null;
|
|
1747
|
-
// Round to common values
|
|
1748
|
-
if (ratio <= 1)
|
|
1749
|
-
return '1';
|
|
1750
|
-
if (ratio <= 1.5)
|
|
1751
|
-
return '1.5';
|
|
1752
|
-
if (ratio <= 2)
|
|
1753
|
-
return '2';
|
|
1754
|
-
if (ratio <= 3)
|
|
1755
|
-
return '3';
|
|
1756
|
-
return '3+';
|
|
1757
|
-
}
|
|
1758
|
-
catch (_a) {
|
|
1759
|
-
return null;
|
|
1760
|
-
}
|
|
1761
|
-
}
|
|
1762
|
-
/**
|
|
1763
|
-
* Coarsen timezone offset for privacy
|
|
1764
|
-
*/
|
|
1765
|
-
coarsenTimezoneOffset() {
|
|
1766
|
-
try {
|
|
1767
|
-
const offset = new Date().getTimezoneOffset();
|
|
1768
|
-
// Round to nearest 30 minutes
|
|
1769
|
-
return Math.round(offset / 30) * 30;
|
|
1770
|
-
}
|
|
1771
|
-
catch (_a) {
|
|
1772
|
-
return null;
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
/**
|
|
1776
|
-
* Test if storage is available
|
|
1777
|
-
*/
|
|
1778
|
-
testStorage(type) {
|
|
1779
|
-
try {
|
|
1780
|
-
const storage = window[type];
|
|
1781
|
-
const testKey = '__dl_test__';
|
|
1782
|
-
storage.setItem(testKey, '1');
|
|
1783
|
-
storage.removeItem(testKey);
|
|
1784
|
-
return true;
|
|
1785
|
-
}
|
|
1786
|
-
catch (_a) {
|
|
1787
|
-
return false;
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
/**
|
|
1791
|
-
* Test if IndexedDB is available
|
|
1792
|
-
*/
|
|
1793
|
-
testIndexedDB() {
|
|
1794
|
-
try {
|
|
1795
|
-
return !!window.indexedDB;
|
|
1796
|
-
}
|
|
1797
|
-
catch (_a) {
|
|
1798
|
-
return false;
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1705
|
+
// PRIVACY: Unused helper methods removed (coarsen functions, storage tests)
|
|
1706
|
+
// Minimal fingerprinting only
|
|
1801
1707
|
/**
|
|
1802
1708
|
* Generate fingerprint hash
|
|
1803
1709
|
*/
|
|
@@ -2437,13 +2343,7 @@ class Datalyr {
|
|
|
2437
2343
|
if (!this.shouldTrack())
|
|
2438
2344
|
return;
|
|
2439
2345
|
try {
|
|
2440
|
-
//
|
|
2441
|
-
if (!this.heavyFingerprintCollected && this.config.enableFingerprinting) {
|
|
2442
|
-
this.heavyFingerprintCollected = true;
|
|
2443
|
-
this.fingerprint.collectHeavyFingerprint().catch(err => {
|
|
2444
|
-
this.log('Heavy fingerprint collection failed:', err);
|
|
2445
|
-
});
|
|
2446
|
-
}
|
|
2346
|
+
// PRIVACY: Heavy fingerprinting removed - using minimal fingerprinting only
|
|
2447
2347
|
// Update session activity
|
|
2448
2348
|
this.session.updateActivity(eventName);
|
|
2449
2349
|
// Create event payload
|