@zaplier/sdk 1.6.1 → 1.6.2
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 +293 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.js +293 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/sdk.js +293 -1
- package/dist/sdk.js.map +1 -1
- package/dist/sdk.min.js +1 -1
- package/dist/src/modules/visitor-persistence.d.ts +20 -88
- package/dist/src/modules/visitor-persistence.d.ts.map +1 -1
- package/dist/src/sdk.d.ts +2 -1
- package/dist/src/sdk.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -748,6 +748,7 @@ declare class ZaplierSDK implements ZaplierSDK$1 {
|
|
|
748
748
|
private heatmapEngine?;
|
|
749
749
|
private antiAdblockManager?;
|
|
750
750
|
private autoTracker?;
|
|
751
|
+
private visitorIdentityManager?;
|
|
751
752
|
constructor(userConfig: SDKConfig);
|
|
752
753
|
/**
|
|
753
754
|
* Initialize SDK
|
|
@@ -776,7 +777,7 @@ declare class ZaplierSDK implements ZaplierSDK$1 {
|
|
|
776
777
|
private initializeAntiAdblock;
|
|
777
778
|
/**
|
|
778
779
|
* Collect fingerprint and generate visitor ID (IMPROVED - 2024)
|
|
779
|
-
* Enhanced with better incognito detection
|
|
780
|
+
* Enhanced with better incognito detection and localStorage persistence
|
|
780
781
|
*/
|
|
781
782
|
private collectFingerprint;
|
|
782
783
|
/**
|
package/dist/index.esm.js
CHANGED
|
@@ -19608,6 +19608,272 @@ class AutoTracker {
|
|
|
19608
19608
|
}
|
|
19609
19609
|
}
|
|
19610
19610
|
|
|
19611
|
+
/**
|
|
19612
|
+
* Visitor Persistence Manager for SDK
|
|
19613
|
+
* Implements client-side visitor identification with localStorage camouflage
|
|
19614
|
+
*/
|
|
19615
|
+
// Camuflaged storage keys to avoid detection/blocking
|
|
19616
|
+
const STORAGE_KEYS = {
|
|
19617
|
+
session: "__zp_s", // Session identifier
|
|
19618
|
+
visitor: "__zp_v", // Visitor identifier (camuflado)
|
|
19619
|
+
device: "__zp_d", // Device fingerprint cache
|
|
19620
|
+
prefs: "__zp_p", // User preferences (decoy storage)
|
|
19621
|
+
analytics: "__zp_a", // Analytics preferences (additional decoy)
|
|
19622
|
+
};
|
|
19623
|
+
/**
|
|
19624
|
+
* Multi-layer persistence manager with fallbacks
|
|
19625
|
+
*/
|
|
19626
|
+
class PersistenceManager {
|
|
19627
|
+
// 1. LocalStorage (primary) - Most persistent
|
|
19628
|
+
static setLocal(key, value) {
|
|
19629
|
+
try {
|
|
19630
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
19631
|
+
localStorage.setItem(key, value);
|
|
19632
|
+
return true;
|
|
19633
|
+
}
|
|
19634
|
+
}
|
|
19635
|
+
catch (e) {
|
|
19636
|
+
// Storage disabled/private mode
|
|
19637
|
+
}
|
|
19638
|
+
return false;
|
|
19639
|
+
}
|
|
19640
|
+
static getLocal(key) {
|
|
19641
|
+
try {
|
|
19642
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
19643
|
+
return localStorage.getItem(key);
|
|
19644
|
+
}
|
|
19645
|
+
}
|
|
19646
|
+
catch (e) {
|
|
19647
|
+
// Storage disabled/private mode
|
|
19648
|
+
}
|
|
19649
|
+
return null;
|
|
19650
|
+
}
|
|
19651
|
+
// 2. SessionStorage (secondary) - Session-only
|
|
19652
|
+
static setSession(key, value) {
|
|
19653
|
+
try {
|
|
19654
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
19655
|
+
sessionStorage.setItem(key, value);
|
|
19656
|
+
return true;
|
|
19657
|
+
}
|
|
19658
|
+
}
|
|
19659
|
+
catch (e) {
|
|
19660
|
+
// Storage disabled/private mode
|
|
19661
|
+
}
|
|
19662
|
+
return false;
|
|
19663
|
+
}
|
|
19664
|
+
static getSession(key) {
|
|
19665
|
+
try {
|
|
19666
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
19667
|
+
return sessionStorage.getItem(key);
|
|
19668
|
+
}
|
|
19669
|
+
}
|
|
19670
|
+
catch (e) {
|
|
19671
|
+
// Storage disabled/private mode
|
|
19672
|
+
}
|
|
19673
|
+
return null;
|
|
19674
|
+
}
|
|
19675
|
+
// 3. Cookie (tertiary) - Cross-session with expiration
|
|
19676
|
+
static setCookie(key, value, days = 365) {
|
|
19677
|
+
try {
|
|
19678
|
+
if (typeof document !== "undefined") {
|
|
19679
|
+
const expires = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toUTCString();
|
|
19680
|
+
document.cookie = `${key}=${value}; expires=${expires}; path=/; SameSite=Lax`;
|
|
19681
|
+
return true;
|
|
19682
|
+
}
|
|
19683
|
+
}
|
|
19684
|
+
catch (e) {
|
|
19685
|
+
// Cookies disabled
|
|
19686
|
+
}
|
|
19687
|
+
return false;
|
|
19688
|
+
}
|
|
19689
|
+
static getCookie(key) {
|
|
19690
|
+
try {
|
|
19691
|
+
if (typeof document !== "undefined") {
|
|
19692
|
+
const name = key + "=";
|
|
19693
|
+
const decodedCookie = decodeURIComponent(document.cookie);
|
|
19694
|
+
const ca = decodedCookie.split(";");
|
|
19695
|
+
for (let i = 0; i < ca.length; i++) {
|
|
19696
|
+
let c = ca[i];
|
|
19697
|
+
if (c) {
|
|
19698
|
+
while (c.charAt(0) === " ") {
|
|
19699
|
+
c = c.substring(1);
|
|
19700
|
+
}
|
|
19701
|
+
if (c.indexOf(name) === 0) {
|
|
19702
|
+
return c.substring(name.length, c.length);
|
|
19703
|
+
}
|
|
19704
|
+
}
|
|
19705
|
+
}
|
|
19706
|
+
}
|
|
19707
|
+
}
|
|
19708
|
+
catch (e) {
|
|
19709
|
+
// Cookies disabled
|
|
19710
|
+
}
|
|
19711
|
+
return null;
|
|
19712
|
+
}
|
|
19713
|
+
// 4. Memory (fallback) - Current session only
|
|
19714
|
+
static setMemory(key, value) {
|
|
19715
|
+
this.memoryStore.set(key, value);
|
|
19716
|
+
return true;
|
|
19717
|
+
}
|
|
19718
|
+
static getMemory(key) {
|
|
19719
|
+
return this.memoryStore.get(key) || null;
|
|
19720
|
+
}
|
|
19721
|
+
// Multi-layer get with fallbacks
|
|
19722
|
+
static get(key) {
|
|
19723
|
+
// Try localStorage first (most persistent)
|
|
19724
|
+
let value = this.getLocal(key);
|
|
19725
|
+
if (value)
|
|
19726
|
+
return { value, method: "localStorage" };
|
|
19727
|
+
// Try sessionStorage (session-only)
|
|
19728
|
+
value = this.getSession(key);
|
|
19729
|
+
if (value)
|
|
19730
|
+
return { value, method: "sessionStorage" };
|
|
19731
|
+
// Try cookies (cross-session)
|
|
19732
|
+
value = this.getCookie(key);
|
|
19733
|
+
if (value)
|
|
19734
|
+
return { value, method: "cookie" };
|
|
19735
|
+
// Try memory (current session)
|
|
19736
|
+
value = this.getMemory(key);
|
|
19737
|
+
if (value)
|
|
19738
|
+
return { value, method: "memory" };
|
|
19739
|
+
return { value: null, method: "none" };
|
|
19740
|
+
}
|
|
19741
|
+
// Multi-layer set with fallbacks
|
|
19742
|
+
static set(key, value) {
|
|
19743
|
+
// Try localStorage first (most persistent)
|
|
19744
|
+
if (this.setLocal(key, value)) {
|
|
19745
|
+
return { success: true, method: "localStorage" };
|
|
19746
|
+
}
|
|
19747
|
+
// Try sessionStorage (session-only)
|
|
19748
|
+
if (this.setSession(key, value)) {
|
|
19749
|
+
return { success: true, method: "sessionStorage" };
|
|
19750
|
+
}
|
|
19751
|
+
// Try cookies (cross-session)
|
|
19752
|
+
if (this.setCookie(key, value)) {
|
|
19753
|
+
return { success: true, method: "cookie" };
|
|
19754
|
+
}
|
|
19755
|
+
// Fallback to memory (current session)
|
|
19756
|
+
this.setMemory(key, value);
|
|
19757
|
+
return { success: true, method: "memory" };
|
|
19758
|
+
}
|
|
19759
|
+
}
|
|
19760
|
+
PersistenceManager.memoryStore = new Map();
|
|
19761
|
+
/**
|
|
19762
|
+
* Advanced Visitor Identity Manager with Camouflaged Storage
|
|
19763
|
+
*/
|
|
19764
|
+
class VisitorIdentityManager {
|
|
19765
|
+
generateVisitorId() {
|
|
19766
|
+
return "vis_" + Array.from(crypto.getRandomValues(new Uint8Array(16)))
|
|
19767
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
19768
|
+
.join('');
|
|
19769
|
+
}
|
|
19770
|
+
generateSessionId() {
|
|
19771
|
+
return "ses_" + Array.from(crypto.getRandomValues(new Uint8Array(8)))
|
|
19772
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
19773
|
+
.join('') + "_" + Date.now().toString(36);
|
|
19774
|
+
}
|
|
19775
|
+
createCamouflageData(visitorId, sessionId, stableCoreHash) {
|
|
19776
|
+
return {
|
|
19777
|
+
theme: "auto",
|
|
19778
|
+
lang: (navigator.language || "en-US").substring(0, 2),
|
|
19779
|
+
tz: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
19780
|
+
analytics: true,
|
|
19781
|
+
cookies: true,
|
|
19782
|
+
_v: visitorId, // Hidden visitor ID
|
|
19783
|
+
_s: sessionId, // Hidden session ID
|
|
19784
|
+
_sc: stableCoreHash, // Hidden stable core
|
|
19785
|
+
ts: Date.now(),
|
|
19786
|
+
};
|
|
19787
|
+
}
|
|
19788
|
+
extractFromCamouflage(data) {
|
|
19789
|
+
try {
|
|
19790
|
+
const parsed = JSON.parse(data);
|
|
19791
|
+
if (parsed._v && parsed._s && parsed._sc) {
|
|
19792
|
+
return {
|
|
19793
|
+
visitorId: parsed._v,
|
|
19794
|
+
sessionId: parsed._s,
|
|
19795
|
+
stableCoreHash: parsed._sc,
|
|
19796
|
+
persistenceMethod: "localStorage",
|
|
19797
|
+
confidence: 0.95,
|
|
19798
|
+
createdAt: parsed.ts || Date.now(),
|
|
19799
|
+
lastSeen: Date.now(),
|
|
19800
|
+
reused: true,
|
|
19801
|
+
};
|
|
19802
|
+
}
|
|
19803
|
+
}
|
|
19804
|
+
catch (e) {
|
|
19805
|
+
// Invalid data
|
|
19806
|
+
}
|
|
19807
|
+
return null;
|
|
19808
|
+
}
|
|
19809
|
+
async getOrCreateVisitorIdentity(params) {
|
|
19810
|
+
const { stableCoreHash } = params;
|
|
19811
|
+
// Try to recover existing identity from camouflaged storage
|
|
19812
|
+
const { value: storedData, method } = PersistenceManager.get(STORAGE_KEYS.prefs);
|
|
19813
|
+
if (storedData) {
|
|
19814
|
+
const existingIdentity = this.extractFromCamouflage(storedData);
|
|
19815
|
+
if (existingIdentity && existingIdentity.stableCoreHash === stableCoreHash) {
|
|
19816
|
+
// Update last seen time
|
|
19817
|
+
const updatedCamouflage = this.createCamouflageData(existingIdentity.visitorId, existingIdentity.sessionId, stableCoreHash);
|
|
19818
|
+
PersistenceManager.set(STORAGE_KEYS.prefs, JSON.stringify(updatedCamouflage));
|
|
19819
|
+
return {
|
|
19820
|
+
...existingIdentity,
|
|
19821
|
+
persistenceMethod: method,
|
|
19822
|
+
lastSeen: Date.now(),
|
|
19823
|
+
reused: true,
|
|
19824
|
+
};
|
|
19825
|
+
}
|
|
19826
|
+
}
|
|
19827
|
+
// Create new visitor identity
|
|
19828
|
+
const newVisitorId = this.generateVisitorId();
|
|
19829
|
+
const newSessionId = params.sessionId || this.generateSessionId();
|
|
19830
|
+
const newIdentity = {
|
|
19831
|
+
visitorId: newVisitorId,
|
|
19832
|
+
sessionId: newSessionId,
|
|
19833
|
+
stableCoreHash,
|
|
19834
|
+
deviceFingerprint: params.deviceFingerprint,
|
|
19835
|
+
persistenceMethod: "localStorage",
|
|
19836
|
+
confidence: 0.90,
|
|
19837
|
+
createdAt: Date.now(),
|
|
19838
|
+
lastSeen: Date.now(),
|
|
19839
|
+
reused: false,
|
|
19840
|
+
};
|
|
19841
|
+
// Store in camouflaged format
|
|
19842
|
+
const camouflageData = this.createCamouflageData(newVisitorId, newSessionId, stableCoreHash);
|
|
19843
|
+
const { method: storageMethod } = PersistenceManager.set(STORAGE_KEYS.prefs, JSON.stringify(camouflageData));
|
|
19844
|
+
newIdentity.persistenceMethod = storageMethod;
|
|
19845
|
+
// Also store device fingerprint cache for faster lookups
|
|
19846
|
+
PersistenceManager.set(STORAGE_KEYS.device, params.deviceFingerprint);
|
|
19847
|
+
return newIdentity;
|
|
19848
|
+
}
|
|
19849
|
+
// Get current visitor ID without creating new one
|
|
19850
|
+
getCurrentVisitorId() {
|
|
19851
|
+
const { value: storedData } = PersistenceManager.get(STORAGE_KEYS.prefs);
|
|
19852
|
+
if (storedData) {
|
|
19853
|
+
const identity = this.extractFromCamouflage(storedData);
|
|
19854
|
+
return identity?.visitorId || null;
|
|
19855
|
+
}
|
|
19856
|
+
return null;
|
|
19857
|
+
}
|
|
19858
|
+
// Clear all stored identity data
|
|
19859
|
+
clearIdentity() {
|
|
19860
|
+
// Remove from all storage layers
|
|
19861
|
+
try {
|
|
19862
|
+
PersistenceManager.setLocal(STORAGE_KEYS.prefs, "");
|
|
19863
|
+
PersistenceManager.setLocal(STORAGE_KEYS.device, "");
|
|
19864
|
+
PersistenceManager.setSession(STORAGE_KEYS.prefs, "");
|
|
19865
|
+
PersistenceManager.setSession(STORAGE_KEYS.device, "");
|
|
19866
|
+
PersistenceManager.setCookie(STORAGE_KEYS.prefs, "", -1); // Expire immediately
|
|
19867
|
+
PersistenceManager.setCookie(STORAGE_KEYS.device, "", -1);
|
|
19868
|
+
PersistenceManager.setMemory(STORAGE_KEYS.prefs, "");
|
|
19869
|
+
PersistenceManager.setMemory(STORAGE_KEYS.device, "");
|
|
19870
|
+
}
|
|
19871
|
+
catch (e) {
|
|
19872
|
+
// Silent fail
|
|
19873
|
+
}
|
|
19874
|
+
}
|
|
19875
|
+
}
|
|
19876
|
+
|
|
19611
19877
|
/**
|
|
19612
19878
|
* Zaplier SDK v1.0.0
|
|
19613
19879
|
* 100% Cookieless Analytics Tracking
|
|
@@ -20043,10 +20309,12 @@ class ZaplierSDK {
|
|
|
20043
20309
|
}
|
|
20044
20310
|
/**
|
|
20045
20311
|
* Collect fingerprint and generate visitor ID (IMPROVED - 2024)
|
|
20046
|
-
* Enhanced with better incognito detection
|
|
20312
|
+
* Enhanced with better incognito detection and localStorage persistence
|
|
20047
20313
|
*/
|
|
20048
20314
|
async collectFingerprint() {
|
|
20049
20315
|
try {
|
|
20316
|
+
// Initialize visitor identity manager
|
|
20317
|
+
this.visitorIdentityManager = new VisitorIdentityManager();
|
|
20050
20318
|
// Use appropriate fingerprinting based on GDPR mode
|
|
20051
20319
|
const result = this.config.gdprMode
|
|
20052
20320
|
? await getLightweightFingerprint()
|
|
@@ -20064,6 +20332,26 @@ class ZaplierSDK {
|
|
|
20064
20332
|
sdkVersion: this.version,
|
|
20065
20333
|
};
|
|
20066
20334
|
}
|
|
20335
|
+
// Generate or retrieve visitor identity using persistent storage
|
|
20336
|
+
const visitorIdentity = await this.visitorIdentityManager.getOrCreateVisitorIdentity({
|
|
20337
|
+
fingerprintHash: result.data.hash,
|
|
20338
|
+
stableCoreHash: result.data.stableCoreHash,
|
|
20339
|
+
deviceFingerprint: result.data.hash,
|
|
20340
|
+
sessionId: this.sessionId,
|
|
20341
|
+
userAgent: navigator.userAgent,
|
|
20342
|
+
ipAddress: undefined, // Will be determined server-side
|
|
20343
|
+
});
|
|
20344
|
+
// Set the persistent visitor ID
|
|
20345
|
+
this.visitorId = visitorIdentity.visitorId;
|
|
20346
|
+
if (this.config.debug) {
|
|
20347
|
+
console.log("[Zaplier] Visitor identity resolved:", {
|
|
20348
|
+
visitorId: this.visitorId,
|
|
20349
|
+
sessionId: this.sessionId,
|
|
20350
|
+
persistenceMethod: visitorIdentity.persistenceMethod,
|
|
20351
|
+
confidence: visitorIdentity.confidence,
|
|
20352
|
+
isNewVisitor: !visitorIdentity.reused,
|
|
20353
|
+
});
|
|
20354
|
+
}
|
|
20067
20355
|
if (this.config.debug) {
|
|
20068
20356
|
console.log("[Zaplier] Fingerprint collected:", {
|
|
20069
20357
|
components: result.collectedComponents,
|
|
@@ -20170,6 +20458,10 @@ class ZaplierSDK {
|
|
|
20170
20458
|
try {
|
|
20171
20459
|
const payload = {
|
|
20172
20460
|
// workspaceId moved to query parameter
|
|
20461
|
+
// Visitor ID (persistido via localStorage camuflado)
|
|
20462
|
+
visitorId: this.visitorId,
|
|
20463
|
+
// Session ID (gerado por sessão)
|
|
20464
|
+
sessionId: this.sessionId,
|
|
20173
20465
|
fingerprintHash: this.fingerprint?.hash,
|
|
20174
20466
|
stableCoreHash: this.fingerprint?.stableCoreHash,
|
|
20175
20467
|
stableCoreVector: this.fingerprint?.stableCoreVector,
|