@zaplier/sdk 1.6.3 → 1.6.5

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.ts CHANGED
@@ -951,7 +951,8 @@ declare class ZaplierSDK implements ZaplierSDK$1 {
951
951
  */
952
952
  isEnhancedMode(): boolean;
953
953
  /**
954
- * Get visitor ID (real UUID from backend, or fallback)
954
+ * Get visitor ID (prioritizes backend, then persistent storage)
955
+ * ENHANCED: Checks persistent storage if memory values are missing
955
956
  */
956
957
  getVisitorId(): string | null;
957
958
  /**
package/dist/index.esm.js CHANGED
@@ -19769,31 +19769,12 @@ class PersistenceManager {
19769
19769
  PersistenceManager.memoryStore = new Map();
19770
19770
  /**
19771
19771
  * Advanced Visitor Identity Manager with Camouflaged Storage
19772
+ * REFACTORED: No longer generates visitor IDs locally - only manages persistence
19773
+ * Backend is the single source of truth for visitor IDs
19772
19774
  */
19773
19775
  class VisitorIdentityManager {
19774
- generateVisitorId() {
19775
- // Generate UUID v4 format instead of vis_ prefix
19776
- const bytes = crypto.getRandomValues(new Uint8Array(16));
19777
- // Set version 4
19778
- bytes[6] = (bytes[6] & 0x0f) | 0x40;
19779
- // Set variant
19780
- bytes[8] = (bytes[8] & 0x3f) | 0x80;
19781
- const hex = Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
19782
- return `${hex.substr(0, 8)}-${hex.substr(8, 4)}-${hex.substr(12, 4)}-${hex.substr(16, 4)}-${hex.substr(20, 12)}`;
19783
- }
19784
- generateVisitorIdFromHash(hash) {
19785
- // Generate deterministic UUID v4 format from fingerprint hash
19786
- // This ensures same fingerprint = same visitor ID
19787
- const hashExtended = hash.length >= 32 ? hash : (hash + hash + hash + hash).substring(0, 32);
19788
- // Extract hex characters for UUID construction
19789
- const hex = hashExtended.substring(0, 32);
19790
- const chars = hex.split('');
19791
- // Set version 4 and variant bits according to RFC 4122
19792
- chars[12] = '4'; // Version 4
19793
- chars[16] = (parseInt(chars[16] || '0', 16) & 0x3 | 0x8).toString(16); // Variant 10
19794
- // Format as UUID: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
19795
- 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('')}`;
19796
- }
19776
+ // REMOVED: generateVisitorId() and generateVisitorIdFromHash() methods
19777
+ // SDK no longer generates visitor IDs - only backend does
19797
19778
  generateSessionId() {
19798
19779
  return "ses_" + Array.from(crypto.getRandomValues(new Uint8Array(8)))
19799
19780
  .map(b => b.toString(16).padStart(2, '0'))
@@ -19833,14 +19814,18 @@ class VisitorIdentityManager {
19833
19814
  }
19834
19815
  return null;
19835
19816
  }
19817
+ /**
19818
+ * REFACTORED: Get existing visitor identity or prepare for backend response
19819
+ * No longer generates visitor IDs - waits for backend to provide them
19820
+ */
19836
19821
  async getOrCreateVisitorIdentity(params) {
19837
19822
  const { stableCoreHash } = params;
19838
19823
  // Try to recover existing identity from camouflaged storage
19839
19824
  const { value: storedData, method } = PersistenceManager.get(STORAGE_KEYS.prefs);
19840
19825
  if (storedData) {
19841
19826
  const existingIdentity = this.extractFromCamouflage(storedData);
19842
- if (existingIdentity && existingIdentity.stableCoreHash === stableCoreHash) {
19843
- // Update last seen time
19827
+ if (existingIdentity && existingIdentity.stableCoreHash === stableCoreHash && existingIdentity.visitorId) {
19828
+ // Update last seen time only if we have a valid visitor ID from backend
19844
19829
  const updatedCamouflage = this.createCamouflageData(existingIdentity.visitorId, existingIdentity.sessionId, stableCoreHash);
19845
19830
  PersistenceManager.set(STORAGE_KEYS.prefs, JSON.stringify(updatedCamouflage));
19846
19831
  return {
@@ -19851,30 +19836,55 @@ class VisitorIdentityManager {
19851
19836
  };
19852
19837
  }
19853
19838
  }
19854
- // Create new visitor identity (deterministic from fingerprint)
19855
- // Use stableCoreHash for deterministic visitor ID generation
19856
- // This ensures same fingerprint = same visitor ID across devices and sessions
19857
- const deterministicVisitorId = this.generateVisitorIdFromHash(params.stableCoreHash);
19839
+ // CHANGED: Create identity without visitor ID - will be set by backend response
19858
19840
  const newSessionId = params.sessionId || this.generateSessionId();
19859
19841
  const newIdentity = {
19860
- visitorId: deterministicVisitorId,
19842
+ // visitorId: undefined, // Will be set when backend responds
19861
19843
  sessionId: newSessionId,
19862
19844
  stableCoreHash,
19863
19845
  deviceFingerprint: params.deviceFingerprint,
19864
- persistenceMethod: "localStorage",
19846
+ persistenceMethod: "memory", // Start with memory, upgrade after backend response
19865
19847
  confidence: 0.90,
19866
19848
  createdAt: Date.now(),
19867
19849
  lastSeen: Date.now(),
19868
19850
  reused: false,
19851
+ pendingBackendResponse: true, // Flag to indicate waiting for backend
19869
19852
  };
19870
- // Store in camouflaged format
19871
- const camouflageData = this.createCamouflageData(deterministicVisitorId, newSessionId, stableCoreHash);
19872
- const { method: storageMethod } = PersistenceManager.set(STORAGE_KEYS.prefs, JSON.stringify(camouflageData));
19873
- newIdentity.persistenceMethod = storageMethod;
19874
- // Also store device fingerprint cache for faster lookups
19875
- PersistenceManager.set(STORAGE_KEYS.device, params.deviceFingerprint);
19876
19853
  return newIdentity;
19877
19854
  }
19855
+ /**
19856
+ * NEW: Update visitor identity with visitor ID received from backend
19857
+ * This is called after backend responds with the definitive visitor ID
19858
+ */
19859
+ async updateVisitorIdFromBackend(visitorId, stableCoreHash, sessionId) {
19860
+ try {
19861
+ // Create or update camouflaged data with backend visitor ID
19862
+ const currentSessionId = sessionId || this.getCurrentSessionId() || this.generateSessionId();
19863
+ const camouflageData = this.createCamouflageData(visitorId, currentSessionId, stableCoreHash);
19864
+ const { success, method } = PersistenceManager.set(STORAGE_KEYS.prefs, JSON.stringify(camouflageData));
19865
+ if (success) {
19866
+ // Also update device fingerprint cache
19867
+ PersistenceManager.set(STORAGE_KEYS.device, stableCoreHash);
19868
+ return true;
19869
+ }
19870
+ return false;
19871
+ }
19872
+ catch (error) {
19873
+ console.error('[VisitorIdentityManager] Failed to update visitor ID from backend:', error);
19874
+ return false;
19875
+ }
19876
+ }
19877
+ /**
19878
+ * Get current session ID from storage
19879
+ */
19880
+ getCurrentSessionId() {
19881
+ const { value: storedData } = PersistenceManager.get(STORAGE_KEYS.prefs);
19882
+ if (storedData) {
19883
+ const identity = this.extractFromCamouflage(storedData);
19884
+ return identity?.sessionId || null;
19885
+ }
19886
+ return null;
19887
+ }
19878
19888
  // Get current visitor ID without creating new one
19879
19889
  getCurrentVisitorId() {
19880
19890
  const { value: storedData } = PersistenceManager.get(STORAGE_KEYS.prefs);
@@ -19934,7 +19944,7 @@ const DEFAULT_CONFIG = {
19934
19944
  */
19935
19945
  class ZaplierSDK {
19936
19946
  constructor(userConfig) {
19937
- this.version = "1.6.0";
19947
+ this.version = "1.7.0";
19938
19948
  this.isInitialized = false;
19939
19949
  this.eventQueue = [];
19940
19950
  /**
@@ -20361,7 +20371,8 @@ class ZaplierSDK {
20361
20371
  sdkVersion: this.version,
20362
20372
  };
20363
20373
  }
20364
- // Generate or retrieve visitor identity using persistent storage
20374
+ // CHANGED: Check for existing visitor identity but don't set local visitor ID
20375
+ // Only backend generates visitor IDs now
20365
20376
  const visitorIdentity = await this.visitorIdentityManager.getOrCreateVisitorIdentity({
20366
20377
  fingerprintHash: result.data.hash,
20367
20378
  stableCoreHash: result.data.stableCoreHash,
@@ -20370,8 +20381,13 @@ class ZaplierSDK {
20370
20381
  userAgent: navigator.userAgent,
20371
20382
  ipAddress: undefined, // Will be determined server-side
20372
20383
  });
20373
- // Set the persistent visitor ID
20374
- this.visitorId = visitorIdentity.visitorId;
20384
+ // CHANGED: Only use visitor ID if it exists from previous backend response
20385
+ // Do not generate any visitor IDs locally
20386
+ if (visitorIdentity.visitorId && !visitorIdentity.pendingBackendResponse) {
20387
+ this.visitorId = visitorIdentity.visitorId;
20388
+ this.backendVisitorId = visitorIdentity.visitorId; // Ensure consistency
20389
+ }
20390
+ // If no visitor ID exists, leave both null - backend will provide it
20375
20391
  if (this.config.debug) {
20376
20392
  console.log("[Zaplier] Visitor identity resolved:", {
20377
20393
  visitorId: this.visitorId,
@@ -20487,8 +20503,8 @@ class ZaplierSDK {
20487
20503
  try {
20488
20504
  const payload = {
20489
20505
  // workspaceId moved to query parameter
20490
- // Visitor ID (persistido via localStorage camuflado)
20491
- visitorId: this.visitorId,
20506
+ // CHANGED: Only send visitor ID if it came from backend (not locally generated)
20507
+ visitorId: this.backendVisitorId || this.getVisitorId(),
20492
20508
  // Session ID (gerado por sessão)
20493
20509
  sessionId: this.sessionId,
20494
20510
  fingerprintHash: this.fingerprint?.hash,
@@ -20540,11 +20556,25 @@ class ZaplierSDK {
20540
20556
  gdprMode: this.config.gdprMode,
20541
20557
  };
20542
20558
  const response = await this.makeRequest(`/tracking/event?token=${encodeURIComponent(this.config.token)}`, payload);
20543
- // Store backend visitor ID and session ID from response
20559
+ // ENHANCED: Store backend visitor ID in both memory and persistent storage
20544
20560
  if (response.visitorId) {
20545
20561
  this.backendVisitorId = response.visitorId;
20562
+ // Update persistent storage with backend visitor ID
20563
+ if (this.visitorIdentityManager && this.fingerprint?.stableCoreHash) {
20564
+ try {
20565
+ await this.visitorIdentityManager.updateVisitorIdFromBackend(response.visitorId, this.fingerprint.stableCoreHash, this.sessionId);
20566
+ if (this.config.debug) {
20567
+ console.log("[Zaplier] Backend visitor ID saved to localStorage:", response.visitorId);
20568
+ }
20569
+ }
20570
+ catch (error) {
20571
+ if (this.config.debug) {
20572
+ console.error("[Zaplier] Failed to save backend visitor ID to storage:", error);
20573
+ }
20574
+ }
20575
+ }
20546
20576
  if (this.config.debug) {
20547
- console.log("[Zaplier] Backend visitor ID received:", response.visitorId);
20577
+ console.log("[Zaplier] Backend visitor ID received and processed:", response.visitorId);
20548
20578
  }
20549
20579
  }
20550
20580
  if (response.sessionId) {
@@ -20872,10 +20902,30 @@ class ZaplierSDK {
20872
20902
  return this.config.enhancedTracking === "true" && !this.config.gdprMode;
20873
20903
  }
20874
20904
  /**
20875
- * Get visitor ID (real UUID from backend, or fallback)
20905
+ * Get visitor ID (prioritizes backend, then persistent storage)
20906
+ * ENHANCED: Checks persistent storage if memory values are missing
20876
20907
  */
20877
20908
  getVisitorId() {
20878
- return this.backendVisitorId || this.visitorId || null;
20909
+ // Priority 1: Backend visitor ID from memory (most recent)
20910
+ if (this.backendVisitorId) {
20911
+ return this.backendVisitorId;
20912
+ }
20913
+ // Priority 2: Local visitor ID from memory (deprecated but kept for compatibility)
20914
+ if (this.visitorId) {
20915
+ return this.visitorId;
20916
+ }
20917
+ // Priority 3: Check persistent storage for backend visitor ID
20918
+ if (this.visitorIdentityManager) {
20919
+ const storedVisitorId = this.visitorIdentityManager.getCurrentVisitorId();
20920
+ if (storedVisitorId) {
20921
+ // Update memory cache for future calls
20922
+ this.backendVisitorId = storedVisitorId;
20923
+ this.visitorId = storedVisitorId;
20924
+ return storedVisitorId;
20925
+ }
20926
+ }
20927
+ // No visitor ID available - will be set after first backend response
20928
+ return null;
20879
20929
  }
20880
20930
  /**
20881
20931
  * Get visitor information from backend