@zaplier/sdk 1.6.4 → 1.6.6
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 +109 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.js +109 -49
- package/dist/index.esm.js.map +1 -1
- package/dist/sdk.js +109 -49
- package/dist/sdk.js.map +1 -1
- package/dist/sdk.min.js +1 -1
- package/dist/src/modules/visitor-persistence.d.ts +17 -3
- 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.cjs
CHANGED
|
@@ -19773,37 +19773,18 @@ class PersistenceManager {
|
|
|
19773
19773
|
PersistenceManager.memoryStore = new Map();
|
|
19774
19774
|
/**
|
|
19775
19775
|
* Advanced Visitor Identity Manager with Camouflaged Storage
|
|
19776
|
+
* REFACTORED: No longer generates visitor IDs locally - only manages persistence
|
|
19777
|
+
* Backend is the single source of truth for visitor IDs
|
|
19776
19778
|
*/
|
|
19777
19779
|
class VisitorIdentityManager {
|
|
19778
|
-
generateVisitorId()
|
|
19779
|
-
|
|
19780
|
-
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
19781
|
-
// Set version 4
|
|
19782
|
-
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
19783
|
-
// Set variant
|
|
19784
|
-
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
19785
|
-
const hex = Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
19786
|
-
return `${hex.substr(0, 8)}-${hex.substr(8, 4)}-${hex.substr(12, 4)}-${hex.substr(16, 4)}-${hex.substr(20, 12)}`;
|
|
19787
|
-
}
|
|
19788
|
-
generateVisitorIdFromHash(hash) {
|
|
19789
|
-
// Generate deterministic UUID v4 format from fingerprint hash
|
|
19790
|
-
// This ensures same fingerprint = same visitor ID
|
|
19791
|
-
const hashExtended = hash.length >= 32 ? hash : (hash + hash + hash + hash).substring(0, 32);
|
|
19792
|
-
// Extract hex characters for UUID construction
|
|
19793
|
-
const hex = hashExtended.substring(0, 32);
|
|
19794
|
-
const chars = hex.split('');
|
|
19795
|
-
// Set version 4 and variant bits according to RFC 4122
|
|
19796
|
-
chars[12] = '4'; // Version 4
|
|
19797
|
-
chars[16] = (parseInt(chars[16] || '0', 16) & 0x3 | 0x8).toString(16); // Variant 10
|
|
19798
|
-
// Format as UUID: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
|
19799
|
-
return `${chars.slice(0, 8).join('')}-${chars.slice(8, 12).join('')}-${chars.slice(12, 16).join('')}-${chars.slice(16, 20).join('')}-${chars.slice(20, 32).join('')}`;
|
|
19800
|
-
}
|
|
19780
|
+
// REMOVED: generateVisitorId() and generateVisitorIdFromHash() methods
|
|
19781
|
+
// SDK no longer generates visitor IDs - only backend does
|
|
19801
19782
|
generateSessionId() {
|
|
19802
19783
|
return "ses_" + Array.from(crypto.getRandomValues(new Uint8Array(8)))
|
|
19803
19784
|
.map(b => b.toString(16).padStart(2, '0'))
|
|
19804
19785
|
.join('') + "_" + Date.now().toString(36);
|
|
19805
19786
|
}
|
|
19806
|
-
createCamouflageData(visitorId, sessionId, stableCoreHash) {
|
|
19787
|
+
createCamouflageData(visitorId, sessionId, stableCoreHash, fromBackend = false) {
|
|
19807
19788
|
return {
|
|
19808
19789
|
theme: "auto",
|
|
19809
19790
|
lang: (navigator.language || "en-US").substring(0, 2),
|
|
@@ -19813,13 +19794,16 @@ class VisitorIdentityManager {
|
|
|
19813
19794
|
_v: visitorId, // Hidden visitor ID
|
|
19814
19795
|
_s: sessionId, // Hidden session ID
|
|
19815
19796
|
_sc: stableCoreHash, // Hidden stable core
|
|
19797
|
+
_vb: fromBackend ? true : undefined, // Flag: visitor ID from backend (v1.7.0+)
|
|
19816
19798
|
ts: Date.now(),
|
|
19817
19799
|
};
|
|
19818
19800
|
}
|
|
19819
19801
|
extractFromCamouflage(data) {
|
|
19820
19802
|
try {
|
|
19821
19803
|
const parsed = JSON.parse(data);
|
|
19822
|
-
if
|
|
19804
|
+
// CRITICAL: Only return visitor ID if it came from backend (v1.7.0+)
|
|
19805
|
+
// This invalidates visitor IDs generated by previous SDK versions
|
|
19806
|
+
if (parsed._v && parsed._s && parsed._sc && parsed._vb === true) {
|
|
19823
19807
|
return {
|
|
19824
19808
|
visitorId: parsed._v,
|
|
19825
19809
|
sessionId: parsed._s,
|
|
@@ -19831,20 +19815,29 @@ class VisitorIdentityManager {
|
|
|
19831
19815
|
reused: true,
|
|
19832
19816
|
};
|
|
19833
19817
|
}
|
|
19818
|
+
// If visitor ID exists but doesn't have backend flag, ignore it
|
|
19819
|
+
if (parsed._v && !parsed._vb) {
|
|
19820
|
+
console.log("[VisitorIdentityManager] Ignoring visitor ID from previous SDK version (no backend flag)");
|
|
19821
|
+
return null;
|
|
19822
|
+
}
|
|
19834
19823
|
}
|
|
19835
19824
|
catch (e) {
|
|
19836
19825
|
// Invalid data
|
|
19837
19826
|
}
|
|
19838
19827
|
return null;
|
|
19839
19828
|
}
|
|
19829
|
+
/**
|
|
19830
|
+
* REFACTORED: Get existing visitor identity or prepare for backend response
|
|
19831
|
+
* No longer generates visitor IDs - waits for backend to provide them
|
|
19832
|
+
*/
|
|
19840
19833
|
async getOrCreateVisitorIdentity(params) {
|
|
19841
19834
|
const { stableCoreHash } = params;
|
|
19842
19835
|
// Try to recover existing identity from camouflaged storage
|
|
19843
19836
|
const { value: storedData, method } = PersistenceManager.get(STORAGE_KEYS.prefs);
|
|
19844
19837
|
if (storedData) {
|
|
19845
19838
|
const existingIdentity = this.extractFromCamouflage(storedData);
|
|
19846
|
-
if (existingIdentity && existingIdentity.stableCoreHash === stableCoreHash) {
|
|
19847
|
-
// Update last seen time
|
|
19839
|
+
if (existingIdentity && existingIdentity.stableCoreHash === stableCoreHash && existingIdentity.visitorId) {
|
|
19840
|
+
// Update last seen time only if we have a valid visitor ID from backend
|
|
19848
19841
|
const updatedCamouflage = this.createCamouflageData(existingIdentity.visitorId, existingIdentity.sessionId, stableCoreHash);
|
|
19849
19842
|
PersistenceManager.set(STORAGE_KEYS.prefs, JSON.stringify(updatedCamouflage));
|
|
19850
19843
|
return {
|
|
@@ -19855,30 +19848,56 @@ class VisitorIdentityManager {
|
|
|
19855
19848
|
};
|
|
19856
19849
|
}
|
|
19857
19850
|
}
|
|
19858
|
-
// Create
|
|
19859
|
-
// Use stableCoreHash for deterministic visitor ID generation
|
|
19860
|
-
// This ensures same fingerprint = same visitor ID across devices and sessions
|
|
19861
|
-
const deterministicVisitorId = this.generateVisitorIdFromHash(params.stableCoreHash);
|
|
19851
|
+
// CHANGED: Create identity without visitor ID - will be set by backend response
|
|
19862
19852
|
const newSessionId = params.sessionId || this.generateSessionId();
|
|
19863
19853
|
const newIdentity = {
|
|
19864
|
-
visitorId:
|
|
19854
|
+
// visitorId: undefined, // Will be set when backend responds
|
|
19865
19855
|
sessionId: newSessionId,
|
|
19866
19856
|
stableCoreHash,
|
|
19867
19857
|
deviceFingerprint: params.deviceFingerprint,
|
|
19868
|
-
persistenceMethod: "
|
|
19858
|
+
persistenceMethod: "memory", // Start with memory, upgrade after backend response
|
|
19869
19859
|
confidence: 0.90,
|
|
19870
19860
|
createdAt: Date.now(),
|
|
19871
19861
|
lastSeen: Date.now(),
|
|
19872
19862
|
reused: false,
|
|
19863
|
+
pendingBackendResponse: true, // Flag to indicate waiting for backend
|
|
19873
19864
|
};
|
|
19874
|
-
// Store in camouflaged format
|
|
19875
|
-
const camouflageData = this.createCamouflageData(deterministicVisitorId, newSessionId, stableCoreHash);
|
|
19876
|
-
const { method: storageMethod } = PersistenceManager.set(STORAGE_KEYS.prefs, JSON.stringify(camouflageData));
|
|
19877
|
-
newIdentity.persistenceMethod = storageMethod;
|
|
19878
|
-
// Also store device fingerprint cache for faster lookups
|
|
19879
|
-
PersistenceManager.set(STORAGE_KEYS.device, params.deviceFingerprint);
|
|
19880
19865
|
return newIdentity;
|
|
19881
19866
|
}
|
|
19867
|
+
/**
|
|
19868
|
+
* NEW: Update visitor identity with visitor ID received from backend
|
|
19869
|
+
* This is called after backend responds with the definitive visitor ID
|
|
19870
|
+
*/
|
|
19871
|
+
async updateVisitorIdFromBackend(visitorId, stableCoreHash, sessionId) {
|
|
19872
|
+
try {
|
|
19873
|
+
// Create or update camouflaged data with backend visitor ID
|
|
19874
|
+
const currentSessionId = sessionId || this.getCurrentSessionId() || this.generateSessionId();
|
|
19875
|
+
const camouflageData = this.createCamouflageData(visitorId, currentSessionId, stableCoreHash, true // Mark as coming from backend
|
|
19876
|
+
);
|
|
19877
|
+
const { success, method } = PersistenceManager.set(STORAGE_KEYS.prefs, JSON.stringify(camouflageData));
|
|
19878
|
+
if (success) {
|
|
19879
|
+
// Also update device fingerprint cache
|
|
19880
|
+
PersistenceManager.set(STORAGE_KEYS.device, stableCoreHash);
|
|
19881
|
+
return true;
|
|
19882
|
+
}
|
|
19883
|
+
return false;
|
|
19884
|
+
}
|
|
19885
|
+
catch (error) {
|
|
19886
|
+
console.error('[VisitorIdentityManager] Failed to update visitor ID from backend:', error);
|
|
19887
|
+
return false;
|
|
19888
|
+
}
|
|
19889
|
+
}
|
|
19890
|
+
/**
|
|
19891
|
+
* Get current session ID from storage
|
|
19892
|
+
*/
|
|
19893
|
+
getCurrentSessionId() {
|
|
19894
|
+
const { value: storedData } = PersistenceManager.get(STORAGE_KEYS.prefs);
|
|
19895
|
+
if (storedData) {
|
|
19896
|
+
const identity = this.extractFromCamouflage(storedData);
|
|
19897
|
+
return identity?.sessionId || null;
|
|
19898
|
+
}
|
|
19899
|
+
return null;
|
|
19900
|
+
}
|
|
19882
19901
|
// Get current visitor ID without creating new one
|
|
19883
19902
|
getCurrentVisitorId() {
|
|
19884
19903
|
const { value: storedData } = PersistenceManager.get(STORAGE_KEYS.prefs);
|
|
@@ -19938,7 +19957,7 @@ const DEFAULT_CONFIG = {
|
|
|
19938
19957
|
*/
|
|
19939
19958
|
class ZaplierSDK {
|
|
19940
19959
|
constructor(userConfig) {
|
|
19941
|
-
this.version = "1.
|
|
19960
|
+
this.version = "1.7.0";
|
|
19942
19961
|
this.isInitialized = false;
|
|
19943
19962
|
this.eventQueue = [];
|
|
19944
19963
|
/**
|
|
@@ -20365,7 +20384,8 @@ class ZaplierSDK {
|
|
|
20365
20384
|
sdkVersion: this.version,
|
|
20366
20385
|
};
|
|
20367
20386
|
}
|
|
20368
|
-
//
|
|
20387
|
+
// CHANGED: Check for existing visitor identity but don't set local visitor ID
|
|
20388
|
+
// Only backend generates visitor IDs now
|
|
20369
20389
|
const visitorIdentity = await this.visitorIdentityManager.getOrCreateVisitorIdentity({
|
|
20370
20390
|
fingerprintHash: result.data.hash,
|
|
20371
20391
|
stableCoreHash: result.data.stableCoreHash,
|
|
@@ -20374,8 +20394,13 @@ class ZaplierSDK {
|
|
|
20374
20394
|
userAgent: navigator.userAgent,
|
|
20375
20395
|
ipAddress: undefined, // Will be determined server-side
|
|
20376
20396
|
});
|
|
20377
|
-
//
|
|
20378
|
-
|
|
20397
|
+
// CHANGED: Only use visitor ID if it exists from previous backend response
|
|
20398
|
+
// Do not generate any visitor IDs locally
|
|
20399
|
+
if (visitorIdentity.visitorId && !visitorIdentity.pendingBackendResponse) {
|
|
20400
|
+
this.visitorId = visitorIdentity.visitorId;
|
|
20401
|
+
this.backendVisitorId = visitorIdentity.visitorId; // Ensure consistency
|
|
20402
|
+
}
|
|
20403
|
+
// If no visitor ID exists, leave both null - backend will provide it
|
|
20379
20404
|
if (this.config.debug) {
|
|
20380
20405
|
console.log("[Zaplier] Visitor identity resolved:", {
|
|
20381
20406
|
visitorId: this.visitorId,
|
|
@@ -20491,8 +20516,9 @@ class ZaplierSDK {
|
|
|
20491
20516
|
try {
|
|
20492
20517
|
const payload = {
|
|
20493
20518
|
// workspaceId moved to query parameter
|
|
20494
|
-
//
|
|
20495
|
-
|
|
20519
|
+
// CRITICAL: Only send visitor ID if it definitively came from backend
|
|
20520
|
+
// Never send locally generated visitor IDs from previous SDK versions
|
|
20521
|
+
visitorId: this.backendVisitorId || null,
|
|
20496
20522
|
// Session ID (gerado por sessão)
|
|
20497
20523
|
sessionId: this.sessionId,
|
|
20498
20524
|
fingerprintHash: this.fingerprint?.hash,
|
|
@@ -20544,11 +20570,25 @@ class ZaplierSDK {
|
|
|
20544
20570
|
gdprMode: this.config.gdprMode,
|
|
20545
20571
|
};
|
|
20546
20572
|
const response = await this.makeRequest(`/tracking/event?token=${encodeURIComponent(this.config.token)}`, payload);
|
|
20547
|
-
// Store backend visitor ID
|
|
20573
|
+
// ENHANCED: Store backend visitor ID in both memory and persistent storage
|
|
20548
20574
|
if (response.visitorId) {
|
|
20549
20575
|
this.backendVisitorId = response.visitorId;
|
|
20576
|
+
// Update persistent storage with backend visitor ID
|
|
20577
|
+
if (this.visitorIdentityManager && this.fingerprint?.stableCoreHash) {
|
|
20578
|
+
try {
|
|
20579
|
+
await this.visitorIdentityManager.updateVisitorIdFromBackend(response.visitorId, this.fingerprint.stableCoreHash, this.sessionId);
|
|
20580
|
+
if (this.config.debug) {
|
|
20581
|
+
console.log("[Zaplier] Backend visitor ID saved to localStorage:", response.visitorId);
|
|
20582
|
+
}
|
|
20583
|
+
}
|
|
20584
|
+
catch (error) {
|
|
20585
|
+
if (this.config.debug) {
|
|
20586
|
+
console.error("[Zaplier] Failed to save backend visitor ID to storage:", error);
|
|
20587
|
+
}
|
|
20588
|
+
}
|
|
20589
|
+
}
|
|
20550
20590
|
if (this.config.debug) {
|
|
20551
|
-
console.log("[Zaplier] Backend visitor ID received:", response.visitorId);
|
|
20591
|
+
console.log("[Zaplier] Backend visitor ID received and processed:", response.visitorId);
|
|
20552
20592
|
}
|
|
20553
20593
|
}
|
|
20554
20594
|
if (response.sessionId) {
|
|
@@ -20876,10 +20916,30 @@ class ZaplierSDK {
|
|
|
20876
20916
|
return this.config.enhancedTracking === "true" && !this.config.gdprMode;
|
|
20877
20917
|
}
|
|
20878
20918
|
/**
|
|
20879
|
-
* Get visitor ID (
|
|
20919
|
+
* Get visitor ID (prioritizes backend, then persistent storage)
|
|
20920
|
+
* ENHANCED: Checks persistent storage if memory values are missing
|
|
20880
20921
|
*/
|
|
20881
20922
|
getVisitorId() {
|
|
20882
|
-
|
|
20923
|
+
// Priority 1: Backend visitor ID from memory (most recent)
|
|
20924
|
+
if (this.backendVisitorId) {
|
|
20925
|
+
return this.backendVisitorId;
|
|
20926
|
+
}
|
|
20927
|
+
// Priority 2: Local visitor ID from memory (deprecated but kept for compatibility)
|
|
20928
|
+
if (this.visitorId) {
|
|
20929
|
+
return this.visitorId;
|
|
20930
|
+
}
|
|
20931
|
+
// Priority 3: Check persistent storage for backend visitor ID
|
|
20932
|
+
if (this.visitorIdentityManager) {
|
|
20933
|
+
const storedVisitorId = this.visitorIdentityManager.getCurrentVisitorId();
|
|
20934
|
+
if (storedVisitorId) {
|
|
20935
|
+
// Update memory cache for future calls
|
|
20936
|
+
this.backendVisitorId = storedVisitorId;
|
|
20937
|
+
this.visitorId = storedVisitorId;
|
|
20938
|
+
return storedVisitorId;
|
|
20939
|
+
}
|
|
20940
|
+
}
|
|
20941
|
+
// No visitor ID available - will be set after first backend response
|
|
20942
|
+
return null;
|
|
20883
20943
|
}
|
|
20884
20944
|
/**
|
|
20885
20945
|
* Get visitor information from backend
|