@zaplier/sdk 1.1.2 → 1.1.4
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.cjs +52 -150
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +52 -150
- package/dist/index.esm.js.map +1 -1
- package/dist/sdk.js +52 -150
- package/dist/sdk.js.map +1 -1
- package/dist/sdk.min.js +1 -1
- package/dist/src/modules/fingerprint.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -5690,156 +5690,51 @@ async function collectFingerprint(options = {}) {
|
|
|
5690
5690
|
timezone: browser?.timezone || "unknown",
|
|
5691
5691
|
// PRIORITY 3: Primary language only (most stable language preference)
|
|
5692
5692
|
// Remove secondary languages as they can change more frequently
|
|
5693
|
-
primaryLanguage:
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5693
|
+
primaryLanguage: (() => {
|
|
5694
|
+
try {
|
|
5695
|
+
const languages = browser?.languages;
|
|
5696
|
+
if (Array.isArray(languages) && languages.length > 0 && languages[0]) {
|
|
5697
|
+
return languages[0].toLowerCase().split("-")[0]; // Only language code (en, pt, fr), not region
|
|
5698
|
+
}
|
|
5699
|
+
// Fallback to navigator.language if browser.languages is not available
|
|
5700
|
+
if (typeof navigator !== 'undefined' && navigator.language) {
|
|
5701
|
+
return navigator.language.toLowerCase().split("-")[0];
|
|
5702
|
+
}
|
|
5703
|
+
return "unknown";
|
|
5704
|
+
}
|
|
5705
|
+
catch {
|
|
5706
|
+
return "unknown";
|
|
5707
|
+
}
|
|
5708
|
+
})(),
|
|
5698
5709
|
// PRIORITY 4: Platform (ultra-stable - OS doesn't change)
|
|
5699
5710
|
platform: (browser?.platform || "unknown").toLowerCase(),
|
|
5700
5711
|
// PRIORITY 5: Device type (critical for differentiation, ultra-stable)
|
|
5701
5712
|
deviceType,
|
|
5702
|
-
// PRIORITY 6:
|
|
5703
|
-
//
|
|
5704
|
-
//
|
|
5705
|
-
//
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
if (width >= 2560)
|
|
5728
|
-
return "qhd"; // QHD/WQHD
|
|
5729
|
-
// Standard high-resolution displays
|
|
5730
|
-
if (width >= 2048)
|
|
5731
|
-
return "qxga"; // QXGA
|
|
5732
|
-
if (width >= 1920)
|
|
5733
|
-
return "fhd"; // Full HD 1080p
|
|
5734
|
-
if (width >= 1680)
|
|
5735
|
-
return "wsxga+"; // WSXGA+
|
|
5736
|
-
if (width >= 1600)
|
|
5737
|
-
return "uxga"; // UXGA
|
|
5738
|
-
if (width >= 1440)
|
|
5739
|
-
return "wxga++"; // WXGA++
|
|
5740
|
-
if (width >= 1366)
|
|
5741
|
-
return "hd"; // HD 720p
|
|
5742
|
-
if (width >= 1280)
|
|
5743
|
-
return "sxga"; // SXGA
|
|
5744
|
-
// Tablet and mobile displays
|
|
5745
|
-
if (width >= 1024)
|
|
5746
|
-
return "xga"; // XGA (tablets)
|
|
5747
|
-
if (width >= 768)
|
|
5748
|
-
return "svga"; // SVGA (small tablets)
|
|
5749
|
-
if (width >= 640)
|
|
5750
|
-
return "vga"; // VGA (phones)
|
|
5751
|
-
if (width >= 480)
|
|
5752
|
-
return "hvga"; // HVGA (older phones)
|
|
5753
|
-
if (width >= 320)
|
|
5754
|
-
return "qvga"; // QVGA (legacy phones)
|
|
5755
|
-
return "minimal"; // Sub-QVGA
|
|
5756
|
-
};
|
|
5757
|
-
// Enhanced aspect ratio classification for device type hints
|
|
5758
|
-
const getAspectRatioClass = (width, height) => {
|
|
5759
|
-
if (height === 0)
|
|
5760
|
-
return "unknown";
|
|
5761
|
-
const ratio = width / height;
|
|
5762
|
-
// Ultra-wide displays (gaming, productivity)
|
|
5763
|
-
if (ratio >= 3.0)
|
|
5764
|
-
return "super_ultrawide"; // 32:9+
|
|
5765
|
-
if (ratio >= 2.3)
|
|
5766
|
-
return "ultrawide"; // 21:9
|
|
5767
|
-
if (ratio >= 2.0)
|
|
5768
|
-
return "wide"; // 18:9
|
|
5769
|
-
// Standard desktop ratios
|
|
5770
|
-
if (ratio >= 1.7 && ratio <= 1.8)
|
|
5771
|
-
return "standard"; // 16:9
|
|
5772
|
-
if (ratio >= 1.6 && ratio <= 1.67)
|
|
5773
|
-
return "classic"; // 16:10, 5:3
|
|
5774
|
-
if (ratio >= 1.3 && ratio <= 1.35)
|
|
5775
|
-
return "traditional"; // 4:3
|
|
5776
|
-
// Mobile/portrait ratios
|
|
5777
|
-
if (ratio >= 0.5 && ratio <= 0.8)
|
|
5778
|
-
return "mobile_portrait"; // Phones in portrait
|
|
5779
|
-
if (ratio >= 0.4 && ratio <= 0.5)
|
|
5780
|
-
return "tall_mobile"; // Modern tall phones
|
|
5781
|
-
return "custom"; // Non-standard ratio
|
|
5782
|
-
};
|
|
5783
|
-
// Ensure w and h are valid numbers
|
|
5784
|
-
const width = w || 0;
|
|
5785
|
-
const height = h || 0;
|
|
5786
|
-
// Screen density class based on common DPR patterns
|
|
5787
|
-
const getDensityClass = (pixelRatio) => {
|
|
5788
|
-
if (!pixelRatio)
|
|
5789
|
-
return "standard";
|
|
5790
|
-
if (pixelRatio >= 3.0)
|
|
5791
|
-
return "ultra_high"; // iPhone Plus, high-end Android
|
|
5792
|
-
if (pixelRatio >= 2.0)
|
|
5793
|
-
return "high"; // Retina, standard high-DPI
|
|
5794
|
-
if (pixelRatio >= 1.5)
|
|
5795
|
-
return "medium"; // Mid-range displays
|
|
5796
|
-
if (pixelRatio >= 1.25)
|
|
5797
|
-
return "enhanced"; // Slightly enhanced DPI
|
|
5798
|
-
return "standard"; // Standard 1x displays
|
|
5799
|
-
};
|
|
5800
|
-
// CRITICAL: Do NOT include exact dimensions in stableCoreVector for mobile!
|
|
5801
|
-
// Reason: Screen dimensions change when:
|
|
5802
|
-
// - Chrome address bar appears/disappears (scroll behavior)
|
|
5803
|
-
// - Virtual keyboard opens/closes
|
|
5804
|
-
// - Screen rotates (portrait ↔ landscape)
|
|
5805
|
-
// - Browser zoom changes
|
|
5806
|
-
// These changes would cause stableCoreHash to change, breaking visitor identification
|
|
5807
|
-
//
|
|
5808
|
-
// INSTEAD: Use ONLY stable screen characteristics (bucket, aspect, density)
|
|
5809
|
-
// For device differentiation (S22 vs A54), use:
|
|
5810
|
-
// - screenFrame (bezel measurements)
|
|
5811
|
-
// - Combination of bucket + hardware + display
|
|
5812
|
-
// - Vector similarity in IdentityResolver
|
|
5813
|
-
return {
|
|
5814
|
-
bucket: getScreenBucket(width),
|
|
5815
|
-
aspectClass: getAspectRatioClass(width, height),
|
|
5816
|
-
densityClass: getDensityClass(screen.pixelRatio || window.devicePixelRatio),
|
|
5817
|
-
// Simplified ratio for matching (rounded to prevent micro-variations)
|
|
5818
|
-
ratio: height > 0 ? Math.round((width / height) * 100) / 100 : 0,
|
|
5819
|
-
// Size category for general device classification
|
|
5820
|
-
sizeCategory: width >= 2560
|
|
5821
|
-
? "large"
|
|
5822
|
-
: width >= 1920
|
|
5823
|
-
? "desktop"
|
|
5824
|
-
: width >= 1024
|
|
5825
|
-
? "laptop"
|
|
5826
|
-
: width >= 768
|
|
5827
|
-
? "tablet"
|
|
5828
|
-
: "mobile",
|
|
5829
|
-
// ❌ REMOVED: exact dimensions (causes instability on mobile)
|
|
5830
|
-
// Device differentiation is now handled by:
|
|
5831
|
-
// 1. screenFrame (bezel measurements - stable)
|
|
5832
|
-
// 2. hardware + display combination
|
|
5833
|
-
// 3. Vector similarity in IdentityResolver
|
|
5834
|
-
};
|
|
5835
|
-
})()
|
|
5836
|
-
: {
|
|
5837
|
-
bucket: "unknown",
|
|
5838
|
-
aspectClass: "unknown",
|
|
5839
|
-
densityClass: "unknown",
|
|
5840
|
-
ratio: 0,
|
|
5841
|
-
sizeCategory: "unknown",
|
|
5842
|
-
},
|
|
5713
|
+
// ❌ PRIORITY 6: Screen - REMOVED FROM stableCoreVector
|
|
5714
|
+
// REASON: Screen properties are UNSTABLE across all device types:
|
|
5715
|
+
//
|
|
5716
|
+
// Desktop:
|
|
5717
|
+
// - DevTools changes viewport (lateral vs bottom)
|
|
5718
|
+
// - Browser zoom changes dimensions
|
|
5719
|
+
// - Window resize changes available space
|
|
5720
|
+
//
|
|
5721
|
+
// Mobile:
|
|
5722
|
+
// - Address bar appears/disappears on scroll
|
|
5723
|
+
// - Virtual keyboard opens/closes
|
|
5724
|
+
// - Screen rotation (portrait ↔ landscape)
|
|
5725
|
+
// - Pull-to-refresh changes viewport
|
|
5726
|
+
//
|
|
5727
|
+
// RESULT: Even "bucket" detection is unreliable due to viewport changes
|
|
5728
|
+
//
|
|
5729
|
+
// SOLUTION: Device differentiation now relies ONLY on:
|
|
5730
|
+
// 1. screenFrame (bezel measurements - MORE stable)
|
|
5731
|
+
// 2. hardware (cores, memory, arch - STABLE)
|
|
5732
|
+
// 3. display (color depth, gamut - STABLE)
|
|
5733
|
+
// 4. platform + deviceType + ua (ULTRA-STABLE)
|
|
5734
|
+
// 5. timezone + primaryLanguage (USER-STABLE)
|
|
5735
|
+
//
|
|
5736
|
+
// Note: screen is still collected in full fingerprint for analytics,
|
|
5737
|
+
// but excluded from stableCoreHash to ensure visitor identification stability
|
|
5843
5738
|
// CRITICAL: Do NOT include availability flags (canvas/webgl/audio) in stableCoreVector
|
|
5844
5739
|
// These flags can change between requests due to timeouts, permissions, or hardware issues
|
|
5845
5740
|
// and would cause the stableCoreHash to change, breaking visitor identification
|
|
@@ -6030,12 +5925,13 @@ async function collectFingerprint(options = {}) {
|
|
|
6030
5925
|
};
|
|
6031
5926
|
// ADDITIONAL ENTROPY: Add a deterministic but unique component based on ultra-stable signals
|
|
6032
5927
|
// This helps prevent collisions while maintaining deterministic behavior
|
|
5928
|
+
// Note: screen removed as it's unstable (viewport changes)
|
|
6033
5929
|
const entropyComponents = [
|
|
6034
5930
|
coreVector.ua || "",
|
|
6035
5931
|
coreVector.platform || "",
|
|
6036
5932
|
coreVector.deviceType || "",
|
|
6037
|
-
coreVector.screen?.bucket || "",
|
|
6038
5933
|
coreVector.timezone || "",
|
|
5934
|
+
coreVector.primaryLanguage || "",
|
|
6039
5935
|
].filter(Boolean);
|
|
6040
5936
|
if (entropyComponents.length >= 3) {
|
|
6041
5937
|
// Create a stable entropy string from the most stable components
|
|
@@ -6060,15 +5956,18 @@ async function collectFingerprint(options = {}) {
|
|
|
6060
5956
|
// - Screen frame (can vary slightly)
|
|
6061
5957
|
// - Vendor flavors (can change)
|
|
6062
5958
|
// - Exact hardware values (use buckets)
|
|
6063
|
-
// DEBUG: Log coreVector components
|
|
5959
|
+
// DEBUG: Log coreVector components for monitoring
|
|
6064
5960
|
if (opts.debug ||
|
|
6065
5961
|
(typeof window !== "undefined" && window._rabbitTrackerDebug)) {
|
|
6066
5962
|
console.log("[RabbitTracker DEBUG] coreVector components:", {
|
|
6067
5963
|
ua: coreVector.ua,
|
|
6068
5964
|
platform: coreVector.platform,
|
|
6069
5965
|
deviceType: coreVector.deviceType,
|
|
6070
|
-
screenBucket: coreVector.screen?.bucket,
|
|
6071
5966
|
timezone: coreVector.timezone,
|
|
5967
|
+
primaryLanguage: coreVector.primaryLanguage,
|
|
5968
|
+
hasHardware: !!coreVector.hardware,
|
|
5969
|
+
hasDisplay: !!coreVector.display,
|
|
5970
|
+
hasScreenFrame: !!coreVector.screenFrame,
|
|
6072
5971
|
_entropy: coreVector._entropy,
|
|
6073
5972
|
});
|
|
6074
5973
|
}
|
|
@@ -6114,7 +6013,10 @@ async function collectFingerprint(options = {}) {
|
|
|
6114
6013
|
ua: coreVector.ua,
|
|
6115
6014
|
deviceType: coreVector.deviceType,
|
|
6116
6015
|
platform: coreVector.platform,
|
|
6117
|
-
|
|
6016
|
+
timezone: coreVector.timezone,
|
|
6017
|
+
hasScreenFrame: !!coreVector.screenFrame,
|
|
6018
|
+
hardwareClass: coreVector.hardware?.class,
|
|
6019
|
+
displayClass: coreVector.display?.class,
|
|
6118
6020
|
totalComponentsInHash: Object.keys(enhancedComponentValues).length,
|
|
6119
6021
|
});
|
|
6120
6022
|
}
|