cryptique-sdk 1.0.5 → 1.0.7

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/lib/cjs/index.js CHANGED
@@ -207,6 +207,8 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
207
207
  */
208
208
  // In-memory cache to prevent race conditions in distinct_id generation
209
209
  let _cachedDistinctId = null;
210
+ // Synchronous lock flag to prevent concurrent distinct_id generation
211
+ let _isGeneratingDistinctId = false;
210
212
 
211
213
  const StorageManager = {
212
214
  /**
@@ -517,7 +519,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
517
519
  * All distinct_ids (anonymous and identified) persist in localStorage
518
520
  * Uses in-memory cache to prevent race conditions
519
521
  *
520
- * @returns {string} Current distinct_id
522
+ * @returns {string|Promise<string>} Current distinct_id (may be Promise if generation is in progress)
521
523
  */
522
524
  getDistinctId() {
523
525
  try {
@@ -527,6 +529,19 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
527
529
  return _cachedDistinctId;
528
530
  }
529
531
 
532
+ // If generation is in progress, return cached or wait briefly and retry
533
+ if (_isGeneratingDistinctId) {
534
+ // Check cache again - it might have been set by the concurrent call
535
+ if (_cachedDistinctId) {
536
+ return _cachedDistinctId;
537
+ }
538
+ // If still generating, return a temporary value (shouldn't happen in practice)
539
+ // This prevents infinite loops
540
+ const tempId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
541
+ console.warn('⚠️ [Storage] Concurrent distinctId generation detected, returning temporary ID');
542
+ return tempId;
543
+ }
544
+
530
545
  // First check localStorage (persists across sessions for both anonymous and identified)
531
546
  let distinctId = localStorage.getItem(CONFIG.STORAGE_KEYS.DISTINCT_ID);
532
547
 
@@ -548,21 +563,36 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
548
563
  }
549
564
 
550
565
  // No distinct_id found - generate new anonymous one
551
- const userId = this.getUserId();
552
- distinctId = this.generateAnonymousDistinctId(userId);
553
-
554
- // Store in both localStorage (persist) and sessionStorage (current session)
555
- localStorage.setItem(CONFIG.STORAGE_KEYS.DISTINCT_ID, distinctId);
556
- sessionStorage.setItem(CONFIG.STORAGE_KEYS.DISTINCT_ID, distinctId);
557
-
558
- _cachedDistinctId = distinctId; // Cache it
559
- return distinctId;
566
+ // Set lock BEFORE generating to prevent concurrent generation
567
+ _isGeneratingDistinctId = true;
568
+ try {
569
+ // Double-check localStorage after acquiring lock (another call might have stored it)
570
+ let checkAgain = localStorage.getItem(CONFIG.STORAGE_KEYS.DISTINCT_ID);
571
+ if (checkAgain) {
572
+ sessionStorage.setItem(CONFIG.STORAGE_KEYS.DISTINCT_ID, checkAgain);
573
+ _cachedDistinctId = checkAgain;
574
+ return checkAgain;
575
+ }
576
+
577
+ const userId = this.getUserId();
578
+ distinctId = this.generateAnonymousDistinctId(userId);
579
+
580
+ // Store in both localStorage (persist) and sessionStorage (current session)
581
+ localStorage.setItem(CONFIG.STORAGE_KEYS.DISTINCT_ID, distinctId);
582
+ sessionStorage.setItem(CONFIG.STORAGE_KEYS.DISTINCT_ID, distinctId);
583
+
584
+ _cachedDistinctId = distinctId; // Cache it
585
+ return distinctId;
586
+ } finally {
587
+ _isGeneratingDistinctId = false;
588
+ }
560
589
  } catch (err) {
561
590
  // Fallback: generate temporary distinct_id
562
591
  console.warn('Failed to access storage for distinct_id:', err);
563
592
  const userId = this.getUserId();
564
593
  const fallbackId = this.generateAnonymousDistinctId(userId);
565
594
  _cachedDistinctId = fallbackId; // Cache even fallback
595
+ _isGeneratingDistinctId = false;
566
596
  return fallbackId;
567
597
  }
568
598
  },
@@ -1814,7 +1844,9 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
1814
1844
  if (!sessionData.siteId) sessionData.siteId = currentSiteId;
1815
1845
  if (!sessionData.teamId) sessionData.teamId = null;
1816
1846
  if (!sessionData.userId) sessionData.userId = null;
1817
- if (!sessionData.distinctId) sessionData.distinctId = StorageManager.getDistinctId();
1847
+ // Always sync distinctId from storage to ensure consistency (like user_id)
1848
+ // This ensures we use distinct_id from past sessions if it exists
1849
+ sessionData.distinctId = StorageManager.getDistinctId();
1818
1850
 
1819
1851
  // Time fields
1820
1852
  if (!sessionData.startTime) sessionData.startTime = nowIso();
@@ -4208,6 +4240,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4208
4240
  sessionDataToSend.sessionId = SessionIdManager.getOrCreate();
4209
4241
  }
4210
4242
 
4243
+ // Always sync distinctId from storage before sending to backend
4244
+ sessionDataToSend.distinctId = StorageManager.getDistinctId();
4245
+
4246
+
4211
4247
  // Transform to backend format
4212
4248
  const transformedData = DataTransformer.toBackendFormat(sessionDataToSend);
4213
4249
 
@@ -5385,6 +5421,9 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
5385
5421
  // Save session to storage
5386
5422
  StorageManager.saveSession(sessionData);
5387
5423
 
5424
+ // Always sync distinctId from storage before logging/sending to ensure consistency
5425
+ sessionData.distinctId = StorageManager.getDistinctId();
5426
+
5388
5427
  // Console log raw session data intermittently
5389
5428
  console.log('📊 [Session] Raw Session Data:', {
5390
5429
  sessionData: sessionData,
@@ -6089,23 +6128,67 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6089
6128
  /**
6090
6129
  * Reset identity (logout/anonymous)
6091
6130
  * Generates new anonymous distinct_id and clears identified state
6131
+ * Ensures new anonymous identity exists in backend
6092
6132
  *
6093
6133
  * @returns {Promise<Object>} Result object with new distinct_id
6094
6134
  */
6095
6135
  async reset() {
6096
6136
  try {
6137
+ // Get current session and user data
6138
+ const session = StorageManager.loadSession();
6139
+ if (!session || !session.id) {
6140
+ console.error('❌ [Identity] No active session found');
6141
+ return { success: false, error: 'No active session' };
6142
+ }
6143
+
6144
+ const currentUserId = StorageManager.getUserId();
6145
+ if (!currentUserId) {
6146
+ console.error('❌ [Identity] No user ID found');
6147
+ return { success: false, error: 'No user ID' };
6148
+ }
6149
+
6150
+ const currentSiteId = getCurrentSiteId();
6151
+ if (!currentSiteId) {
6152
+ console.error('❌ [Identity] Site ID not found');
6153
+ return { success: false, error: 'Site ID not found' };
6154
+ }
6155
+
6097
6156
  // Generate new anonymous distinct_id
6098
- const userId = StorageManager.getUserId();
6099
- const newDistinctId = StorageManager.generateAnonymousDistinctId(userId);
6157
+ const newDistinctId = StorageManager.generateAnonymousDistinctId(currentUserId);
6100
6158
 
6101
- // Clear identified distinct_id from localStorage (setDistinctId will handle this)
6102
- // Update sessionStorage with new anonymous distinct_id
6159
+ // Call backend endpoint to ensure new anonymous identity exists
6160
+ const apiUrl = CONFIG.API.TRACK.replace('/track', '/reset');
6161
+ const response = await fetch(apiUrl, {
6162
+ method: 'POST',
6163
+ headers: {
6164
+ 'Content-Type': 'application/json',
6165
+ 'X-Cryptique-Site-Id': currentSiteId
6166
+ },
6167
+ body: JSON.stringify({
6168
+ siteId: currentSiteId,
6169
+ sessionId: session.id,
6170
+ userId: currentUserId,
6171
+ distinctId: newDistinctId
6172
+ })
6173
+ });
6174
+
6175
+ if (!response.ok) {
6176
+ const errorData = await response.text();
6177
+ console.error('❌ [Identity] Reset API error:', {
6178
+ status: response.status,
6179
+ statusText: response.statusText,
6180
+ error: errorData
6181
+ });
6182
+ throw new Error(`Reset API error: ${response.status} ${response.statusText} - ${errorData}`);
6183
+ }
6184
+
6185
+ const result = await response.json();
6186
+
6187
+ // Update local storage after backend confirms
6103
6188
  StorageManager.setDistinctId(newDistinctId);
6104
-
6105
- // Clear the cache to ensure fresh distinct_id generation
6106
6189
  StorageManager.clearDistinctIdCache();
6107
6190
 
6108
- // Update sessionData first
6191
+ // Update sessionData
6109
6192
  if (sessionData) {
6110
6193
  sessionData.distinctId = newDistinctId;
6111
6194
  sessionData.anonymous = true;
@@ -6113,12 +6196,12 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6113
6196
  }
6114
6197
 
6115
6198
  // Update stored session
6116
- const session = StorageManager.loadSession();
6117
- if (session) {
6118
- session.distinctId = newDistinctId;
6119
- session.anonymous = true;
6120
- session.identified = false;
6121
- StorageManager.saveSession(session);
6199
+ const updatedSession = StorageManager.loadSession();
6200
+ if (updatedSession) {
6201
+ updatedSession.distinctId = newDistinctId;
6202
+ updatedSession.anonymous = true;
6203
+ updatedSession.identified = false;
6204
+ StorageManager.saveSession(updatedSession);
6122
6205
  }
6123
6206
 
6124
6207
  // Clear identify_id from storage (if stored separately)
@@ -6130,7 +6213,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6130
6213
  }
6131
6214
 
6132
6215
  console.log(`🔄 [Identity] Reset to anonymous: ${newDistinctId}`);
6133
-
6216
+
6134
6217
  return { success: true, distinctId: newDistinctId };
6135
6218
  } catch (error) {
6136
6219
  console.error('❌ [Identity] Error in reset():', error);
@@ -6658,14 +6741,20 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6658
6741
 
6659
6742
  try {
6660
6743
  const session = StorageManager.loadSession();
6661
- const currentUserId = StorageManager.getUserId();
6744
+ const currentDistinctId = StorageManager.getDistinctId();
6745
+ // #region agent log
6746
+ fetch('http://127.0.0.1:7242/ingest/0a56a3e4-8313-4f9f-bf29-80309bdcd0db',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'sdkcopy.js:6822',message:'PeopleManager.set entry',data:{currentDistinctId,siteId:getCurrentSiteId()},timestamp:Date.now(),sessionId:'debug-session',runId:'post-fix',hypothesisId:'A'})}).catch(()=>{});
6747
+ // #endregion
6662
6748
 
6663
- if (!session || !currentUserId || !SITE_ID) {
6664
- console.error('❌ [People] No active session or user ID found');
6749
+ if (!session || !currentDistinctId || !SITE_ID) {
6750
+ console.error('❌ [People] No active session or distinct ID found');
6665
6751
  return { success: false, error: 'No active session' };
6666
6752
  }
6667
6753
 
6668
6754
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/set');
6755
+ // #region agent log
6756
+ fetch('http://127.0.0.1:7242/ingest/0a56a3e4-8313-4f9f-bf29-80309bdcd0db',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'sdkcopy.js:6837',message:'PeopleManager.set API call',data:{apiUrl,userId:currentDistinctId,siteId:getCurrentSiteId()},timestamp:Date.now(),sessionId:'debug-session',runId:'post-fix',hypothesisId:'A'})}).catch(()=>{});
6757
+ // #endregion
6669
6758
  const response = await fetch(apiUrl, {
6670
6759
  method: 'POST',
6671
6760
  headers: {
@@ -6674,7 +6763,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6674
6763
  },
6675
6764
  body: JSON.stringify({
6676
6765
  siteId: getCurrentSiteId(),
6677
- userId: currentUserId,
6766
+ userId: currentDistinctId,
6678
6767
  properties: properties
6679
6768
  })
6680
6769
  });
@@ -6708,10 +6797,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6708
6797
 
6709
6798
  try {
6710
6799
  const session = StorageManager.loadSession();
6711
- const currentUserId = StorageManager.getUserId();
6800
+ const currentDistinctId = StorageManager.getDistinctId();
6712
6801
 
6713
- if (!session || !currentUserId || !SITE_ID) {
6714
- console.error('❌ [People] No active session or user ID found');
6802
+ if (!session || !currentDistinctId || !SITE_ID) {
6803
+ console.error('❌ [People] No active session or distinct ID found');
6715
6804
  return { success: false, error: 'No active session' };
6716
6805
  }
6717
6806
 
@@ -6724,7 +6813,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6724
6813
  },
6725
6814
  body: JSON.stringify({
6726
6815
  siteId: getCurrentSiteId(),
6727
- userId: currentUserId,
6816
+ userId: currentDistinctId,
6728
6817
  properties: properties
6729
6818
  })
6730
6819
  });
@@ -6758,10 +6847,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6758
6847
 
6759
6848
  try {
6760
6849
  const session = StorageManager.loadSession();
6761
- const currentUserId = StorageManager.getUserId();
6850
+ const currentDistinctId = StorageManager.getDistinctId();
6762
6851
 
6763
- if (!session || !currentUserId || !SITE_ID) {
6764
- console.error('❌ [People] No active session or user ID found');
6852
+ if (!session || !currentDistinctId || !SITE_ID) {
6853
+ console.error('❌ [People] No active session or distinct ID found');
6765
6854
  return { success: false, error: 'No active session' };
6766
6855
  }
6767
6856
 
@@ -6774,7 +6863,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6774
6863
  },
6775
6864
  body: JSON.stringify({
6776
6865
  siteId: getCurrentSiteId(),
6777
- userId: currentUserId,
6866
+ userId: currentDistinctId,
6778
6867
  keys: keys
6779
6868
  })
6780
6869
  });
@@ -6814,10 +6903,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6814
6903
 
6815
6904
  try {
6816
6905
  const session = StorageManager.loadSession();
6817
- const currentUserId = StorageManager.getUserId();
6906
+ const currentDistinctId = StorageManager.getDistinctId();
6818
6907
 
6819
- if (!session || !currentUserId || !SITE_ID) {
6820
- console.error('❌ [People] No active session or user ID found');
6908
+ if (!session || !currentDistinctId || !SITE_ID) {
6909
+ console.error('❌ [People] No active session or distinct ID found');
6821
6910
  return { success: false, error: 'No active session' };
6822
6911
  }
6823
6912
 
@@ -6830,7 +6919,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6830
6919
  },
6831
6920
  body: JSON.stringify({
6832
6921
  siteId: getCurrentSiteId(),
6833
- userId: currentUserId,
6922
+ userId: currentDistinctId,
6834
6923
  key: key,
6835
6924
  amount: amount
6836
6925
  })
@@ -6871,10 +6960,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6871
6960
 
6872
6961
  try {
6873
6962
  const session = StorageManager.loadSession();
6874
- const currentUserId = StorageManager.getUserId();
6963
+ const currentDistinctId = StorageManager.getDistinctId();
6875
6964
 
6876
- if (!session || !currentUserId || !SITE_ID) {
6877
- console.error('❌ [People] No active session or user ID found');
6965
+ if (!session || !currentDistinctId || !SITE_ID) {
6966
+ console.error('❌ [People] No active session or distinct ID found');
6878
6967
  return { success: false, error: 'No active session' };
6879
6968
  }
6880
6969
 
@@ -6887,7 +6976,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6887
6976
  },
6888
6977
  body: JSON.stringify({
6889
6978
  siteId: getCurrentSiteId(),
6890
- userId: currentUserId,
6979
+ userId: currentDistinctId,
6891
6980
  key: key,
6892
6981
  values: values
6893
6982
  })
@@ -6928,10 +7017,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6928
7017
 
6929
7018
  try {
6930
7019
  const session = StorageManager.loadSession();
6931
- const currentUserId = StorageManager.getUserId();
7020
+ const currentDistinctId = StorageManager.getDistinctId();
6932
7021
 
6933
- if (!session || !currentUserId || !SITE_ID) {
6934
- console.error('❌ [People] No active session or user ID found');
7022
+ if (!session || !currentDistinctId || !SITE_ID) {
7023
+ console.error('❌ [People] No active session or distinct ID found');
6935
7024
  return { success: false, error: 'No active session' };
6936
7025
  }
6937
7026
 
@@ -6944,7 +7033,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6944
7033
  },
6945
7034
  body: JSON.stringify({
6946
7035
  siteId: getCurrentSiteId(),
6947
- userId: currentUserId,
7036
+ userId: currentDistinctId,
6948
7037
  key: key,
6949
7038
  values: values
6950
7039
  })
@@ -6985,10 +7074,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6985
7074
 
6986
7075
  try {
6987
7076
  const session = StorageManager.loadSession();
6988
- const currentUserId = StorageManager.getUserId();
7077
+ const currentDistinctId = StorageManager.getDistinctId();
6989
7078
 
6990
- if (!session || !currentUserId || !SITE_ID) {
6991
- console.error('❌ [People] No active session or user ID found');
7079
+ if (!session || !currentDistinctId || !SITE_ID) {
7080
+ console.error('❌ [People] No active session or distinct ID found');
6992
7081
  return { success: false, error: 'No active session' };
6993
7082
  }
6994
7083
 
@@ -7001,7 +7090,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7001
7090
  },
7002
7091
  body: JSON.stringify({
7003
7092
  siteId: getCurrentSiteId(),
7004
- userId: currentUserId,
7093
+ userId: currentDistinctId,
7005
7094
  key: key,
7006
7095
  values: values
7007
7096
  })
@@ -7037,10 +7126,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7037
7126
 
7038
7127
  try {
7039
7128
  const session = StorageManager.loadSession();
7040
- const currentUserId = StorageManager.getUserId();
7129
+ const currentDistinctId = StorageManager.getDistinctId();
7041
7130
 
7042
- if (!session || !currentUserId || !SITE_ID) {
7043
- console.error('❌ [People] No active session or user ID found');
7131
+ if (!session || !currentDistinctId || !SITE_ID) {
7132
+ console.error('❌ [People] No active session or distinct ID found');
7044
7133
  return { success: false, error: 'No active session' };
7045
7134
  }
7046
7135
 
@@ -7053,7 +7142,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7053
7142
  },
7054
7143
  body: JSON.stringify({
7055
7144
  siteId: getCurrentSiteId(),
7056
- userId: currentUserId,
7145
+ userId: currentDistinctId,
7057
7146
  amount: amount,
7058
7147
  properties: properties
7059
7148
  })
@@ -7082,10 +7171,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7082
7171
  async clearCharges() {
7083
7172
  try {
7084
7173
  const session = StorageManager.loadSession();
7085
- const currentUserId = StorageManager.getUserId();
7174
+ const currentDistinctId = StorageManager.getDistinctId();
7086
7175
 
7087
- if (!session || !currentUserId || !SITE_ID) {
7088
- console.error('❌ [People] No active session or user ID found');
7176
+ if (!session || !currentDistinctId || !SITE_ID) {
7177
+ console.error('❌ [People] No active session or distinct ID found');
7089
7178
  return { success: false, error: 'No active session' };
7090
7179
  }
7091
7180
 
@@ -7098,7 +7187,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7098
7187
  },
7099
7188
  body: JSON.stringify({
7100
7189
  siteId: getCurrentSiteId(),
7101
- userId: currentUserId
7190
+ userId: currentDistinctId
7102
7191
  })
7103
7192
  });
7104
7193
 
@@ -7125,10 +7214,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7125
7214
  async deleteUser() {
7126
7215
  try {
7127
7216
  const session = StorageManager.loadSession();
7128
- const currentUserId = StorageManager.getUserId();
7217
+ const currentDistinctId = StorageManager.getDistinctId();
7129
7218
 
7130
- if (!session || !currentUserId || !SITE_ID) {
7131
- console.error('❌ [People] No active session or user ID found');
7219
+ if (!session || !currentDistinctId || !SITE_ID) {
7220
+ console.error('❌ [People] No active session or distinct ID found');
7132
7221
  return { success: false, error: 'No active session' };
7133
7222
  }
7134
7223
 
@@ -7141,7 +7230,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7141
7230
  },
7142
7231
  body: JSON.stringify({
7143
7232
  siteId: getCurrentSiteId(),
7144
- userId: currentUserId
7233
+ userId: currentDistinctId
7145
7234
  })
7146
7235
  });
7147
7236