cryptique-sdk 1.2.22 → 1.2.24

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/umd/index.js CHANGED
@@ -572,47 +572,6 @@
572
572
  });
573
573
  },
574
574
 
575
- /**
576
- * Call backend to migrate all sessions from old userId to new UUID
577
- *
578
- * This ensures that when a user's localStorage userId is migrated from old format
579
- * to UUID v4, all their existing sessions in the database are also updated to use
580
- * the new UUID, preventing session splitting.
581
- *
582
- * @param {string} siteId - The site ID
583
- * @param {string} oldUserId - Old format userId (e.g., "usr_abc123xyz")
584
- * @param {string} newUserId - New UUID v4 userId
585
- * @returns {Promise<Object>} Migration result with success status and updated count
586
- */
587
- async migrateUserIdOnBackend(siteId, oldUserId, newUserId) {
588
- try {
589
- // Construct migration endpoint URL from track endpoint
590
- const migrationUrl = CONFIG.API.TRACK.replace('/track', '/migrate-user-id');
591
-
592
- const response = await _nativeFetch(migrationUrl, {
593
- method: 'POST',
594
- headers: {
595
- 'Content-Type': 'application/json'
596
- },
597
- body: JSON.stringify({
598
- siteId: siteId,
599
- oldUserId: oldUserId,
600
- newUserId: newUserId
601
- })
602
- });
603
-
604
- if (!response.ok) {
605
- const errorText = await response.text();
606
- throw new Error(`Migration failed: ${response.status} - ${errorText}`);
607
- }
608
-
609
- const result = await response.json();
610
- return result;
611
- } catch (error) {
612
- throw error;
613
- }
614
- },
615
-
616
575
  /**
617
576
  * Get or create persistent user ID
618
577
  *
@@ -625,11 +584,8 @@
625
584
  * - Globally unique across all sites and teams
626
585
  * - Cryptographically secure
627
586
  * - No collisions possible
628
- *
629
- * MIGRATION:
630
- * - Automatically migrates old format ("usr_abc123xyz") to UUID v4
631
- * - Calls backend to migrate all existing sessions to new UUID
632
- * - Validates UUID format on retrieval
587
+ *
588
+ * Non-UUID values in storage are replaced with a new UUID v4.
633
589
  */
634
590
  getUserId() {
635
591
  try {
@@ -640,39 +596,8 @@
640
596
  userId = this.generateUUIDv4();
641
597
  localStorage.setItem(CONFIG.STORAGE_KEYS.USER_ID, userId);
642
598
  } else {
643
- // Validate format and migrate if needed
644
599
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
645
- const oldFormatRegex = /^usr_[a-z0-9]{9}$/;
646
- const oldTempFormatRegex = /^usr_temp_[a-z0-9]{9}$/;
647
-
648
- // Check if old format detected
649
- if (oldFormatRegex.test(userId) || oldTempFormatRegex.test(userId)) {
650
- const oldUserId = userId; // Store old before migration
651
- const newUserId = this.generateUUIDv4(); // Generate new UUID
652
-
653
-
654
- // CRITICAL: Store new UUID in localStorage IMMEDIATELY
655
- // This prevents multiple migrations if getUserId() is called again
656
- localStorage.setItem(CONFIG.STORAGE_KEYS.USER_ID, newUserId);
657
-
658
- // Call backend to migrate all sessions (non-blocking)
659
- if (SITE_ID) {
660
- this.migrateUserIdOnBackend(SITE_ID, oldUserId, newUserId)
661
- .then((result) => {
662
- if (result.success) {
663
- } else {
664
- console.warn('⚠️ Migration failed, but continuing with new UUID');
665
- }
666
- })
667
- .catch((err) => {
668
- // UUID already stored in localStorage, migration can happen later
669
- });
670
- }
671
-
672
- // Return new UUID immediately (already stored in localStorage)
673
- userId = newUserId;
674
- } else if (!uuidRegex.test(userId)) {
675
- // Invalid format - regenerate
600
+ if (!uuidRegex.test(userId)) {
676
601
  userId = this.generateUUIDv4();
677
602
  localStorage.setItem(CONFIG.STORAGE_KEYS.USER_ID, userId);
678
603
  }
@@ -2020,8 +1945,8 @@
2020
1945
  initialize() {
2021
1946
  // Ensure all required fields exist (some may already be set)
2022
1947
  if (!sessionData.sessionId) sessionData.sessionId = null;
2023
- // Get current SITE_ID (may have been set via init() after SDK loaded)
2024
- const currentSiteId = SITE_ID || window.Cryptique?.siteId || window.__CRYPTIQUE_SITE_ID__ || null;
1948
+ // May have been set via init() after SDK loaded
1949
+ const currentSiteId = getCurrentSiteId();
2025
1950
  if (!sessionData.siteId) sessionData.siteId = currentSiteId;
2026
1951
  if (!sessionData.teamId) sessionData.teamId = null;
2027
1952
  if (!sessionData.userId) sessionData.userId = null;
@@ -4115,7 +4040,7 @@
4115
4040
  utm_id: utmData.utm_id,
4116
4041
  session_id: sessionData.sessionId,
4117
4042
  wallet_address: sessionData.wallet_address,
4118
- siteId: SITE_ID
4043
+ siteId: getCurrentSiteId()
4119
4044
  };
4120
4045
 
4121
4046
  // Send PATCH request to update wallet address
@@ -6855,7 +6780,7 @@
6855
6780
  return { success: false, error: 'No user ID' };
6856
6781
  }
6857
6782
 
6858
- if (!SITE_ID) {
6783
+ if (!getCurrentSiteId()) {
6859
6784
  console.error('❌ [Identity] Site ID not found');
6860
6785
  return { success: false, error: 'Site ID not found' };
6861
6786
  }
@@ -7638,7 +7563,7 @@
7638
7563
  const session = StorageManager.loadSession();
7639
7564
  const currentDistinctId = StorageManager.getDistinctId();
7640
7565
 
7641
- if (!session || !currentDistinctId || !SITE_ID) {
7566
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
7642
7567
  console.error('❌ [People] No active session or distinct ID found');
7643
7568
  return { success: false, error: 'No active session' };
7644
7569
  }
@@ -7687,7 +7612,7 @@
7687
7612
  const session = StorageManager.loadSession();
7688
7613
  const currentDistinctId = StorageManager.getDistinctId();
7689
7614
 
7690
- if (!session || !currentDistinctId || !SITE_ID) {
7615
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
7691
7616
  console.error('❌ [People] No active session or distinct ID found');
7692
7617
  return { success: false, error: 'No active session' };
7693
7618
  }
@@ -7736,7 +7661,7 @@
7736
7661
  const session = StorageManager.loadSession();
7737
7662
  const currentDistinctId = StorageManager.getDistinctId();
7738
7663
 
7739
- if (!session || !currentDistinctId || !SITE_ID) {
7664
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
7740
7665
  console.error('❌ [People] No active session or distinct ID found');
7741
7666
  return { success: false, error: 'No active session' };
7742
7667
  }
@@ -7791,7 +7716,7 @@
7791
7716
  const session = StorageManager.loadSession();
7792
7717
  const currentDistinctId = StorageManager.getDistinctId();
7793
7718
 
7794
- if (!session || !currentDistinctId || !SITE_ID) {
7719
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
7795
7720
  console.error('❌ [People] No active session or distinct ID found');
7796
7721
  return { success: false, error: 'No active session' };
7797
7722
  }
@@ -7847,7 +7772,7 @@
7847
7772
  const session = StorageManager.loadSession();
7848
7773
  const currentDistinctId = StorageManager.getDistinctId();
7849
7774
 
7850
- if (!session || !currentDistinctId || !SITE_ID) {
7775
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
7851
7776
  console.error('❌ [People] No active session or distinct ID found');
7852
7777
  return { success: false, error: 'No active session' };
7853
7778
  }
@@ -7903,7 +7828,7 @@
7903
7828
  const session = StorageManager.loadSession();
7904
7829
  const currentDistinctId = StorageManager.getDistinctId();
7905
7830
 
7906
- if (!session || !currentDistinctId || !SITE_ID) {
7831
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
7907
7832
  console.error('❌ [People] No active session or distinct ID found');
7908
7833
  return { success: false, error: 'No active session' };
7909
7834
  }
@@ -7959,7 +7884,7 @@
7959
7884
  const session = StorageManager.loadSession();
7960
7885
  const currentDistinctId = StorageManager.getDistinctId();
7961
7886
 
7962
- if (!session || !currentDistinctId || !SITE_ID) {
7887
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
7963
7888
  console.error('❌ [People] No active session or distinct ID found');
7964
7889
  return { success: false, error: 'No active session' };
7965
7890
  }
@@ -8010,7 +7935,7 @@
8010
7935
  const session = StorageManager.loadSession();
8011
7936
  const currentDistinctId = StorageManager.getDistinctId();
8012
7937
 
8013
- if (!session || !currentDistinctId || !SITE_ID) {
7938
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
8014
7939
  console.error('❌ [People] No active session or distinct ID found');
8015
7940
  return { success: false, error: 'No active session' };
8016
7941
  }
@@ -8054,7 +7979,7 @@
8054
7979
  const session = StorageManager.loadSession();
8055
7980
  const currentDistinctId = StorageManager.getDistinctId();
8056
7981
 
8057
- if (!session || !currentDistinctId || !SITE_ID) {
7982
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
8058
7983
  console.error('❌ [People] No active session or distinct ID found');
8059
7984
  return { success: false, error: 'No active session' };
8060
7985
  }
@@ -8096,7 +8021,7 @@
8096
8021
  const session = StorageManager.loadSession();
8097
8022
  const currentDistinctId = StorageManager.getDistinctId();
8098
8023
 
8099
- if (!session || !currentDistinctId || !SITE_ID) {
8024
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
8100
8025
  console.error('❌ [People] No active session or distinct ID found');
8101
8026
  return { success: false, error: 'No active session' };
8102
8027
  }
@@ -8251,6 +8176,12 @@
8251
8176
  },
8252
8177
  delete() {
8253
8178
  return mgr._profileCall('delete', groupKey, groupId, {});
8179
+ },
8180
+ increment(property, value = 1) {
8181
+ return mgr._profileCall('increment', groupKey, groupId, { property, value });
8182
+ },
8183
+ append(property, value) {
8184
+ return mgr._profileCall('append', groupKey, groupId, { property, value });
8254
8185
  }
8255
8186
  };
8256
8187
  },
@@ -8263,7 +8194,7 @@
8263
8194
  try {
8264
8195
  const session = StorageManager.loadSession();
8265
8196
  const currentDistinctId = StorageManager.getDistinctId();
8266
- if (!session || !currentDistinctId || !SITE_ID) {
8197
+ if (!session || !currentDistinctId || !getCurrentSiteId()) {
8267
8198
  console.error('❌ [Groups] No active session or distinct ID found');
8268
8199
  return { success: false, error: 'No active session' };
8269
8200
  }
@@ -8553,620 +8484,624 @@
8553
8484
 
8554
8485
  }
8555
8486
 
8556
- /**
8557
- * Cryptique Analytics SDK - NPM Module Entry Point
8558
- *
8559
- * This is a thin wrapper around script/script.js that exports the SDK
8560
- * as a module for npm usage. All functionality remains in script.js.
8561
- *
8562
- * The script.js file is inlined during the build process by Rollup.
8563
- */
8564
-
8565
-
8566
- // Create a wrapper that provides programmatic initialization
8567
- const CryptiqueSDK = {
8568
- /**
8569
- * Initialize the SDK programmatically
8570
- * @param {Object} options - Configuration options
8571
- * @param {string} options.siteId - Site ID (required)
8572
- * @param {boolean} [options.autoEvents] - Enable auto events (default: false)
8573
- * @param {string[]} [options.disabledPaths] - Paths to disable auto events
8574
- * @param {string[]} [options.disabledEvents] - Auto events to disable
8575
- */
8576
- init(options = {}) {
8577
- if (typeof window === 'undefined') {
8578
- console.warn('Cryptique SDK requires a browser environment');
8579
- return Promise.resolve(null);
8580
- }
8581
-
8582
- if (!options.siteId) {
8583
- throw new Error('siteId is required');
8584
- }
8585
-
8586
- // Wait for SDK to be available on window
8587
- const checkSDK = () => {
8588
- if (window.Cryptique) {
8589
- // Set site ID
8590
- window.Cryptique.siteId = options.siteId;
8591
-
8592
- // Configure auto events if provided
8593
- if (options.autoEvents !== undefined) {
8594
- if (options.autoEvents) {
8595
- window.Cryptique.enableAutoEvents();
8596
- } else {
8597
- window.Cryptique.disableAutoEvents();
8598
- }
8599
- }
8600
-
8601
- // Set disabled paths if provided
8602
- if (options.disabledPaths) {
8603
- if (window.Cryptique.setAutoEventsDisabledPaths) {
8604
- window.Cryptique.setAutoEventsDisabledPaths(options.disabledPaths);
8605
- }
8606
- }
8607
-
8608
- // Set disabled events if provided
8609
- if (options.disabledEvents) {
8610
- if (window.Cryptique.setAutoEventsDisabledEvents) {
8611
- window.Cryptique.setAutoEventsDisabledEvents(options.disabledEvents);
8612
- }
8613
- }
8614
-
8615
- return window.Cryptique;
8616
- }
8617
- return null;
8618
- };
8619
-
8620
- // If SDK is already loaded, configure and return ready promise
8621
- if (window.Cryptique) {
8622
- checkSDK();
8623
- // Return ready() so await Cryptique.init() waits for full initialization
8624
- return window.Cryptique.ready ? window.Cryptique.ready() : Promise.resolve(window.Cryptique);
8625
- }
8626
-
8627
- // Otherwise, wait for SDK to load then configure and wait for ready
8628
- return new Promise((resolve) => {
8629
- const maxAttempts = 50;
8630
- let attempts = 0;
8631
- const interval = setInterval(() => {
8632
- attempts++;
8633
- const sdk = checkSDK();
8634
- if (sdk) {
8635
- clearInterval(interval);
8636
- // Wait for full initialization
8637
- const readyPromise = sdk.ready ? sdk.ready() : Promise.resolve(sdk);
8638
- resolve(readyPromise);
8639
- } else if (attempts >= maxAttempts) {
8640
- clearInterval(interval);
8641
- resolve(null);
8642
- }
8643
- }, 100);
8644
- });
8645
- },
8646
-
8647
- /**
8648
- * Get the SDK instance
8649
- * Returns window.Cryptique if available
8650
- */
8651
- getInstance() {
8652
- if (typeof window !== 'undefined' && window.Cryptique) {
8653
- return window.Cryptique;
8654
- }
8655
- return null;
8656
- },
8657
-
8658
- /**
8659
- * Wait for SDK to be fully initialized
8660
- * Returns a Promise that resolves when initialization is complete
8661
- * @returns {Promise<void>}
8662
- */
8663
- ready() {
8664
- const instance = this.getInstance();
8665
- if (instance && instance.ready) {
8666
- return instance.ready();
8667
- }
8668
- return Promise.resolve();
8669
- },
8670
-
8671
- /**
8672
- * Identify a user with a unique identifier
8673
- *
8674
- * When called, checks if this identify_id exists for another user.
8675
- * If found, merges the current user_id with the existing user_id.
8676
- *
8677
- * @param {string} identifyId - Unique identifier for the user
8678
- * @returns {Promise<Object>} Result object with merged status and new userId
8679
- */
8680
- async identify(identifyId) {
8681
- const instance = this.getInstance();
8682
- if (instance && instance.identify) {
8683
- return await instance.identify(identifyId);
8684
- }
8685
- throw new Error('SDK not initialized. Call init() first.');
8686
- },
8687
-
8688
- /**
8689
- * Set wallet address for current user
8690
- *
8691
- * If wallet address already exists for another user, merges identities.
8692
- * Otherwise, sets wallet address for current user.
8693
- *
8694
- * @param {string} walletAddress - Wallet address to set
8695
- * @returns {Promise<Object>} Result object with merged status and new userId
8696
- */
8697
- async walletAddress(walletAddress) {
8698
- const instance = this.getInstance();
8699
- if (instance && instance.walletAddress) {
8700
- return await instance.walletAddress(walletAddress);
8701
- }
8702
- throw new Error('SDK not initialized. Call init() first.');
8703
- },
8704
-
8705
- /**
8706
- * Reset user identity to anonymous
8707
- *
8708
- * Generates a new anonymous distinct_id and clears identification.
8709
- * Useful for privacy/GDPR compliance when user wants to reset their identity.
8710
- *
8711
- * @returns {Promise<Object>} Result object with success status and new distinctId
8712
- */
8713
- async reset() {
8714
- const instance = this.getInstance();
8715
- if (instance && instance.reset) {
8716
- return await instance.reset();
8717
- }
8718
- throw new Error('SDK not initialized. Call init() first.');
8719
- },
8720
-
8721
- /**
8722
- * Track a custom event
8723
- * @param {string} eventName - Name of the event
8724
- * @param {Object} [properties] - Event properties
8725
- * @param {Object} [options] - Event options
8726
- * @returns {Promise<void>}
8727
- */
8728
- async track(eventName, properties, options) {
8729
- const instance = this.getInstance();
8730
- if (instance && instance.track) {
8731
- return await instance.track(eventName, properties, options);
8732
- }
8733
- throw new Error('SDK not initialized. Call init() first.');
8734
- },
8735
-
8736
- /**
8737
- * Track a custom event (alias for track)
8738
- * @param {string} eventName - Name of the event
8739
- * @param {Object} [properties] - Event properties
8740
- * @param {Object} [options] - Event options
8741
- * @returns {Promise<void>}
8742
- */
8743
- async trackEvent(eventName, properties, options) {
8744
- const instance = this.getInstance();
8745
- if (instance && instance.trackEvent) {
8746
- return await instance.trackEvent(eventName, properties, options);
8747
- }
8748
- throw new Error('SDK not initialized. Call init() first.');
8749
- },
8750
-
8751
- /**
8752
- * Track an auto event
8753
- * @param {string} eventName - Name of the auto event
8754
- * @param {Object} [autoEventData] - Auto event data
8755
- * @param {Object} [elementData] - Element data
8756
- * @returns {Promise<void>}
8757
- */
8758
- async trackAutoEvent(eventName, autoEventData, elementData) {
8759
- const instance = this.getInstance();
8760
- if (instance && instance.trackAutoEvent) {
8761
- return await instance.trackAutoEvent(eventName, autoEventData, elementData);
8762
- }
8763
- throw new Error('SDK not initialized. Call init() first.');
8764
- },
8765
-
8766
- /**
8767
- * Connect wallet
8768
- * @returns {Promise<string|null>} Wallet address or null
8769
- */
8770
- async connectWallet() {
8771
- const instance = this.getInstance();
8772
- if (instance && instance.connectWallet) {
8773
- return await instance.connectWallet();
8774
- }
8775
- throw new Error('SDK not initialized. Call init() first.');
8776
- },
8777
-
8778
- /**
8779
- * Check if wallet is connected
8780
- * @returns {Promise<boolean>}
8781
- */
8782
- async isWalletConnected() {
8783
- const instance = this.getInstance();
8784
- if (instance && instance.isWalletConnected) {
8785
- return await instance.isWalletConnected();
8786
- }
8787
- throw new Error('SDK not initialized. Call init() first.');
8788
- },
8789
-
8790
- /**
8791
- * Update wallet info
8792
- * @returns {Promise<any>}
8793
- */
8794
- async updateWalletInfo() {
8795
- const instance = this.getInstance();
8796
- if (instance && instance.updateWalletInfo) {
8797
- return await instance.updateWalletInfo();
8798
- }
8799
- throw new Error('SDK not initialized. Call init() first.');
8800
- },
8801
-
8802
- /**
8803
- * Set tracking consent
8804
- * @param {boolean} consent - Consent value
8805
- */
8806
- setTrackingConsent(consent) {
8807
- const instance = this.getInstance();
8808
- if (instance && instance.setTrackingConsent) {
8809
- return instance.setTrackingConsent(consent);
8810
- }
8811
- throw new Error('SDK not initialized. Call init() first.');
8812
- },
8813
-
8814
- /**
8815
- * Get tracking consent
8816
- * @returns {boolean}
8817
- */
8818
- getTrackingConsent() {
8819
- const instance = this.getInstance();
8820
- if (instance && instance.getTrackingConsent) {
8821
- return instance.getTrackingConsent();
8822
- }
8823
- return false;
8824
- },
8825
-
8826
- /**
8827
- * Get session data
8828
- * @returns {Object}
8829
- */
8830
- getSessionData() {
8831
- const instance = this.getInstance();
8832
- if (instance && instance.getSessionData) {
8833
- return instance.getSessionData();
8834
- }
8835
- return null;
8836
- },
8837
-
8838
- /**
8839
- * Get chronological interactions
8840
- * @returns {Array}
8841
- */
8842
- getChronologicalInteractions() {
8843
- const instance = this.getInstance();
8844
- if (instance && instance.getChronologicalInteractions) {
8845
- return instance.getChronologicalInteractions();
8846
- }
8847
- return [];
8848
- },
8849
-
8850
- /**
8851
- * Sort interactions chronologically (alias)
8852
- * @returns {Array}
8853
- */
8854
- sortInteractionsChronologically() {
8855
- const instance = this.getInstance();
8856
- if (instance && instance.sortInteractionsChronologically) {
8857
- return instance.sortInteractionsChronologically();
8858
- }
8859
- return [];
8860
- },
8861
-
8862
- /**
8863
- * Enable auto events
8864
- */
8865
- enableAutoEvents() {
8866
- const instance = this.getInstance();
8867
- if (instance && instance.enableAutoEvents) {
8868
- return instance.enableAutoEvents();
8869
- }
8870
- },
8871
-
8872
- /**
8873
- * Disable auto events
8874
- */
8875
- disableAutoEvents() {
8876
- const instance = this.getInstance();
8877
- if (instance && instance.disableAutoEvents) {
8878
- return instance.disableAutoEvents();
8879
- }
8880
- },
8881
-
8882
- /**
8883
- * Set auto events disabled paths
8884
- * @param {string|string[]} paths - Paths to disable
8885
- */
8886
- setAutoEventsDisabledPaths(paths) {
8887
- const instance = this.getInstance();
8888
- if (instance && instance.setAutoEventsDisabledPaths) {
8889
- return instance.setAutoEventsDisabledPaths(paths);
8890
- }
8891
- },
8892
-
8893
- /**
8894
- * Disable specific auto events
8895
- * @param {string|string[]} events - Event name(s) to disable
8896
- */
8897
- disableAutoEvent(events) {
8898
- const instance = this.getInstance();
8899
- if (instance && instance.disableAutoEvent) {
8900
- return instance.disableAutoEvent(events);
8901
- }
8902
- },
8903
-
8904
- /**
8905
- * Enable specific auto events
8906
- * @param {string|string[]} events - Event name(s) to enable
8907
- */
8908
- enableAutoEvent(events) {
8909
- const instance = this.getInstance();
8910
- if (instance && instance.enableAutoEvent) {
8911
- return instance.enableAutoEvent(events);
8912
- }
8913
- },
8914
-
8915
- /**
8916
- * Set auto events disabled events
8917
- * @param {string[]} events - Array of event names to disable
8918
- */
8919
- setAutoEventsDisabledEvents(events) {
8920
- const instance = this.getInstance();
8921
- if (instance && instance.setAutoEventsDisabledEvents) {
8922
- return instance.setAutoEventsDisabledEvents(events);
8923
- }
8924
- },
8925
-
8926
- /**
8927
- * Get available auto events
8928
- * @returns {string[]}
8929
- */
8930
- getAvailableAutoEvents() {
8931
- const instance = this.getInstance();
8932
- if (instance && instance.getAvailableAutoEvents) {
8933
- return instance.getAvailableAutoEvents();
8934
- }
8935
- return [];
8936
- },
8937
-
8938
- /**
8939
- * Get auto events configuration
8940
- * @returns {Object}
8941
- */
8942
- getAutoEventsConfig() {
8943
- const instance = this.getInstance();
8944
- if (instance && instance.getAutoEventsConfig) {
8945
- return instance.getAutoEventsConfig();
8946
- }
8947
- return null;
8948
- },
8949
-
8950
- /**
8951
- * People object for managing user properties
8952
- */
8953
- get people() {
8954
- const instance = this.getInstance();
8955
- if (instance && instance.people) {
8956
- return instance.people;
8957
- }
8958
- // Return a stub object that will work once SDK is initialized
8959
- return {
8960
- set: async (properties) => {
8961
- const inst = this.getInstance();
8962
- if (inst && inst.people && inst.people.set) {
8963
- return await inst.people.set(properties);
8964
- }
8965
- throw new Error('SDK not initialized. Call init() first.');
8966
- },
8967
- setOnce: async (properties) => {
8968
- const inst = this.getInstance();
8969
- if (inst && inst.people && inst.people.setOnce) {
8970
- return await inst.people.setOnce(properties);
8971
- }
8972
- throw new Error('SDK not initialized. Call init() first.');
8973
- },
8974
- unset: async (properties) => {
8975
- const inst = this.getInstance();
8976
- if (inst && inst.people && inst.people.unset) {
8977
- return await inst.people.unset(properties);
8978
- }
8979
- throw new Error('SDK not initialized. Call init() first.');
8980
- },
8981
- increment: async (properties) => {
8982
- const inst = this.getInstance();
8983
- if (inst && inst.people && inst.people.increment) {
8984
- return await inst.people.increment(properties);
8985
- }
8986
- throw new Error('SDK not initialized. Call init() first.');
8987
- },
8988
- append: async (properties) => {
8989
- const inst = this.getInstance();
8990
- if (inst && inst.people && inst.people.append) {
8991
- return await inst.people.append(properties);
8992
- }
8993
- throw new Error('SDK not initialized. Call init() first.');
8994
- },
8995
- union: async (properties) => {
8996
- const inst = this.getInstance();
8997
- if (inst && inst.people && inst.people.union) {
8998
- return await inst.people.union(properties);
8999
- }
9000
- throw new Error('SDK not initialized. Call init() first.');
9001
- },
9002
- remove: async (properties) => {
9003
- const inst = this.getInstance();
9004
- if (inst && inst.people && inst.people.remove) {
9005
- return await inst.people.remove(properties);
9006
- }
9007
- throw new Error('SDK not initialized. Call init() first.');
9008
- },
9009
- trackCharge: async (amount, properties) => {
9010
- const inst = this.getInstance();
9011
- if (inst && inst.people && inst.people.trackCharge) {
9012
- return await inst.people.trackCharge(amount, properties);
9013
- }
9014
- throw new Error('SDK not initialized. Call init() first.');
9015
- },
9016
- clearCharges: async () => {
9017
- const inst = this.getInstance();
9018
- if (inst && inst.people && inst.people.clearCharges) {
9019
- return await inst.people.clearCharges();
9020
- }
9021
- throw new Error('SDK not initialized. Call init() first.');
9022
- },
9023
- deleteUser: async () => {
9024
- const inst = this.getInstance();
9025
- if (inst && inst.people && inst.people.deleteUser) {
9026
- return await inst.people.deleteUser();
9027
- }
9028
- throw new Error('SDK not initialized. Call init() first.');
9029
- }
9030
- };
9031
- },
9032
-
9033
- // -------------------------------------------------------------------------
9034
- // Group Methods
9035
- // -------------------------------------------------------------------------
9036
-
9037
- /**
9038
- * Set (overwrite) the user's group membership for a given key.
9039
- * @param {string} groupKey - The group type key (e.g. 'company_id')
9040
- * @param {string|string[]} groupId - The group ID(s) to assign
9041
- * @returns {Promise<Object>}
9042
- */
9043
- async set_group(groupKey, groupId) {
9044
- const instance = this.getInstance();
9045
- if (instance && instance.set_group) {
9046
- return await instance.set_group(groupKey, groupId);
9047
- }
9048
- throw new Error('SDK not initialized. Call init() first.');
9049
- },
9050
-
9051
- /**
9052
- * Add a group ID to an existing group key without removing current memberships.
9053
- * @param {string} groupKey - The group type key (e.g. 'company_id')
9054
- * @param {string} groupId - The single group ID to add
9055
- * @returns {Promise<Object>}
9056
- */
9057
- async add_group(groupKey, groupId) {
9058
- const instance = this.getInstance();
9059
- if (instance && instance.add_group) {
9060
- return await instance.add_group(groupKey, groupId);
9061
- }
9062
- throw new Error('SDK not initialized. Call init() first.');
9063
- },
9064
-
9065
- /**
9066
- * Remove a specific group ID from the user's group membership.
9067
- * @param {string} groupKey - The group type key (e.g. 'company_id')
9068
- * @param {string} groupId - The group ID to remove
9069
- * @returns {Promise<Object>}
9070
- */
9071
- async remove_group(groupKey, groupId) {
9072
- const instance = this.getInstance();
9073
- if (instance && instance.remove_group) {
9074
- return await instance.remove_group(groupKey, groupId);
9075
- }
9076
- throw new Error('SDK not initialized. Call init() first.');
9077
- },
9078
-
9079
- /**
9080
- * Get a group profile reference object for performing profile operations.
9081
- *
9082
- * Returns a synchronous object with the following methods:
9083
- * .set(properties) – Set group profile properties
9084
- * .set_once(properties) – Set properties only if not already set
9085
- * .union(listName, values) – Add values to a list property (no duplicates)
9086
- * .remove(listName, value) – Remove a value from a list property
9087
- * .unset(property) – Remove a property from the group profile
9088
- * .delete() Delete the entire group profile
9089
- *
9090
- * @param {string} groupKey - The group type key (e.g. 'company_id')
9091
- * @param {string} groupId - The specific group ID
9092
- * @returns {Object} Group profile reference object
9093
- *
9094
- * @example
9095
- * const group = Cryptique.get_group('company', 'acme-corp');
9096
- * await group.set({ plan: 'enterprise', employees: 500 });
9097
- * await group.set_once({ created_at: new Date().toISOString() });
9098
- * await group.union('tags', ['b2b', 'saas']);
9099
- * await group.unset('old_property');
9100
- * await group.delete();
9101
- */
9102
- get_group(groupKey, groupId) {
9103
- const instance = this.getInstance();
9104
- if (instance && instance.get_group) {
9105
- return instance.get_group(groupKey, groupId);
9106
- }
9107
- // Return a stub whose methods all throw if SDK not yet ready
9108
- const notReady = () => { throw new Error('SDK not initialized. Call init() first.'); };
9109
- return {
9110
- set: notReady,
9111
- set_once: notReady,
9112
- union: notReady,
9113
- remove: notReady,
9114
- unset: notReady,
9115
- delete: notReady
9116
- };
9117
- }
9118
- };
9119
-
9120
- // Proxy all methods from window.Cryptique to our export
9121
- // This will be populated after script.js loads
9122
- // Also sync properties that might not be methods
9123
- const syncMethods = () => {
9124
- if (typeof window !== 'undefined' && window.Cryptique) {
9125
- Object.keys(window.Cryptique).forEach(key => {
9126
- // Skip if we already have a custom implementation
9127
- if (['people', 'set_group', 'add_group', 'remove_group', 'get_group'].includes(key) || CryptiqueSDK.hasOwnProperty(key)) {
9128
- return;
9129
- }
9130
-
9131
- if (typeof window.Cryptique[key] === 'function') {
9132
- CryptiqueSDK[key] = window.Cryptique[key].bind(window.Cryptique);
9133
- } else {
9134
- CryptiqueSDK[key] = window.Cryptique[key];
9135
- }
9136
- });
9137
-
9138
- // Sync version and siteId properties
9139
- if (window.Cryptique.version) {
9140
- CryptiqueSDK.version = window.Cryptique.version;
9141
- }
9142
- if (window.Cryptique.siteId) {
9143
- CryptiqueSDK.siteId = window.Cryptique.siteId;
9144
- }
9145
- if (window.Cryptique.sessionData) {
9146
- CryptiqueSDK.sessionData = window.Cryptique.sessionData;
9147
- }
9148
- }
9149
- };
9150
-
9151
- // Try to sync immediately if SDK is already loaded
9152
- if (typeof window !== 'undefined') {
9153
- syncMethods();
9154
-
9155
- // Also sync after DOM loads (in case script loads async)
9156
- if (window.addEventListener) {
9157
- window.addEventListener('load', syncMethods);
9158
- if (document.readyState === 'loading') {
9159
- document.addEventListener('DOMContentLoaded', syncMethods);
9160
- } else {
9161
- syncMethods();
9162
- }
9163
- }
9164
- }
9165
-
9166
- // Export for CommonJS
9167
- if (typeof module !== 'undefined' && module.exports) {
9168
- module.exports = CryptiqueSDK;
9169
- module.exports.default = CryptiqueSDK;
8487
+ /**
8488
+ * Cryptique Analytics SDK - NPM Module Entry Point
8489
+ *
8490
+ * This is a thin wrapper around script/script.js that exports the SDK
8491
+ * as a module for npm usage. All functionality remains in script.js.
8492
+ *
8493
+ * The script.js file is inlined during the build process by Rollup.
8494
+ */
8495
+
8496
+
8497
+ // Create a wrapper that provides programmatic initialization
8498
+ const CryptiqueSDK = {
8499
+ /**
8500
+ * Initialize the SDK programmatically
8501
+ * @param {Object} options - Configuration options
8502
+ * @param {string} options.siteId - Site ID (required)
8503
+ * @param {boolean} [options.autoEvents] - Enable auto events (default: false)
8504
+ * @param {string[]} [options.disabledPaths] - Paths to disable auto events
8505
+ * @param {string[]} [options.disabledEvents] - Auto events to disable
8506
+ */
8507
+ init(options = {}) {
8508
+ if (typeof window === 'undefined') {
8509
+ console.warn('Cryptique SDK requires a browser environment');
8510
+ return Promise.resolve(null);
8511
+ }
8512
+
8513
+ if (!options.siteId) {
8514
+ throw new Error('siteId is required');
8515
+ }
8516
+
8517
+ // Wait for SDK to be available on window
8518
+ const checkSDK = () => {
8519
+ if (window.Cryptique) {
8520
+ // Set site ID
8521
+ window.Cryptique.siteId = options.siteId;
8522
+
8523
+ // Configure auto events if provided
8524
+ if (options.autoEvents !== undefined) {
8525
+ if (options.autoEvents) {
8526
+ window.Cryptique.enableAutoEvents();
8527
+ } else {
8528
+ window.Cryptique.disableAutoEvents();
8529
+ }
8530
+ }
8531
+
8532
+ // Set disabled paths if provided
8533
+ if (options.disabledPaths) {
8534
+ if (window.Cryptique.setAutoEventsDisabledPaths) {
8535
+ window.Cryptique.setAutoEventsDisabledPaths(options.disabledPaths);
8536
+ }
8537
+ }
8538
+
8539
+ // Set disabled events if provided
8540
+ if (options.disabledEvents) {
8541
+ if (window.Cryptique.setAutoEventsDisabledEvents) {
8542
+ window.Cryptique.setAutoEventsDisabledEvents(options.disabledEvents);
8543
+ }
8544
+ }
8545
+
8546
+ return window.Cryptique;
8547
+ }
8548
+ return null;
8549
+ };
8550
+
8551
+ // If SDK is already loaded, configure and return ready promise
8552
+ if (window.Cryptique) {
8553
+ checkSDK();
8554
+ // Return ready() so await Cryptique.init() waits for full initialization
8555
+ return window.Cryptique.ready ? window.Cryptique.ready() : Promise.resolve(window.Cryptique);
8556
+ }
8557
+
8558
+ // Otherwise, wait for SDK to load then configure and wait for ready
8559
+ return new Promise((resolve) => {
8560
+ const maxAttempts = 50;
8561
+ let attempts = 0;
8562
+ const interval = setInterval(() => {
8563
+ attempts++;
8564
+ const sdk = checkSDK();
8565
+ if (sdk) {
8566
+ clearInterval(interval);
8567
+ // Wait for full initialization
8568
+ const readyPromise = sdk.ready ? sdk.ready() : Promise.resolve(sdk);
8569
+ resolve(readyPromise);
8570
+ } else if (attempts >= maxAttempts) {
8571
+ clearInterval(interval);
8572
+ resolve(null);
8573
+ }
8574
+ }, 100);
8575
+ });
8576
+ },
8577
+
8578
+ /**
8579
+ * Get the SDK instance
8580
+ * Returns window.Cryptique if available
8581
+ */
8582
+ getInstance() {
8583
+ if (typeof window !== 'undefined' && window.Cryptique) {
8584
+ return window.Cryptique;
8585
+ }
8586
+ return null;
8587
+ },
8588
+
8589
+ /**
8590
+ * Wait for SDK to be fully initialized
8591
+ * Returns a Promise that resolves when initialization is complete
8592
+ * @returns {Promise<void>}
8593
+ */
8594
+ ready() {
8595
+ const instance = this.getInstance();
8596
+ if (instance && instance.ready) {
8597
+ return instance.ready();
8598
+ }
8599
+ return Promise.resolve();
8600
+ },
8601
+
8602
+ /**
8603
+ * Identify a user with a unique identifier
8604
+ *
8605
+ * When called, checks if this identify_id exists for another user.
8606
+ * If found, merges the current user_id with the existing user_id.
8607
+ *
8608
+ * @param {string} identifyId - Unique identifier for the user
8609
+ * @returns {Promise<Object>} Result object with merged status and new userId
8610
+ */
8611
+ async identify(identifyId) {
8612
+ const instance = this.getInstance();
8613
+ if (instance && instance.identify) {
8614
+ return await instance.identify(identifyId);
8615
+ }
8616
+ throw new Error('SDK not initialized. Call init() first.');
8617
+ },
8618
+
8619
+ /**
8620
+ * Set wallet address for current user
8621
+ *
8622
+ * If wallet address already exists for another user, merges identities.
8623
+ * Otherwise, sets wallet address for current user.
8624
+ *
8625
+ * @param {string} walletAddress - Wallet address to set
8626
+ * @returns {Promise<Object>} Result object with merged status and new userId
8627
+ */
8628
+ async walletAddress(walletAddress) {
8629
+ const instance = this.getInstance();
8630
+ if (instance && instance.walletAddress) {
8631
+ return await instance.walletAddress(walletAddress);
8632
+ }
8633
+ throw new Error('SDK not initialized. Call init() first.');
8634
+ },
8635
+
8636
+ /**
8637
+ * Reset user identity to anonymous
8638
+ *
8639
+ * Generates a new anonymous distinct_id and clears identification.
8640
+ * Useful for privacy/GDPR compliance when user wants to reset their identity.
8641
+ *
8642
+ * @returns {Promise<Object>} Result object with success status and new distinctId
8643
+ */
8644
+ async reset() {
8645
+ const instance = this.getInstance();
8646
+ if (instance && instance.reset) {
8647
+ return await instance.reset();
8648
+ }
8649
+ throw new Error('SDK not initialized. Call init() first.');
8650
+ },
8651
+
8652
+ /**
8653
+ * Track a custom event
8654
+ * @param {string} eventName - Name of the event
8655
+ * @param {Object} [properties] - Event properties
8656
+ * @param {Object} [options] - Event options
8657
+ * @returns {Promise<void>}
8658
+ */
8659
+ async track(eventName, properties, options) {
8660
+ const instance = this.getInstance();
8661
+ if (instance && instance.track) {
8662
+ return await instance.track(eventName, properties, options);
8663
+ }
8664
+ throw new Error('SDK not initialized. Call init() first.');
8665
+ },
8666
+
8667
+ /**
8668
+ * Track a custom event (alias for track)
8669
+ * @param {string} eventName - Name of the event
8670
+ * @param {Object} [properties] - Event properties
8671
+ * @param {Object} [options] - Event options
8672
+ * @returns {Promise<void>}
8673
+ */
8674
+ async trackEvent(eventName, properties, options) {
8675
+ const instance = this.getInstance();
8676
+ if (instance && instance.trackEvent) {
8677
+ return await instance.trackEvent(eventName, properties, options);
8678
+ }
8679
+ throw new Error('SDK not initialized. Call init() first.');
8680
+ },
8681
+
8682
+ /**
8683
+ * Track an auto event
8684
+ * @param {string} eventName - Name of the auto event
8685
+ * @param {Object} [autoEventData] - Auto event data
8686
+ * @param {Object} [elementData] - Element data
8687
+ * @returns {Promise<void>}
8688
+ */
8689
+ async trackAutoEvent(eventName, autoEventData, elementData) {
8690
+ const instance = this.getInstance();
8691
+ if (instance && instance.trackAutoEvent) {
8692
+ return await instance.trackAutoEvent(eventName, autoEventData, elementData);
8693
+ }
8694
+ throw new Error('SDK not initialized. Call init() first.');
8695
+ },
8696
+
8697
+ /**
8698
+ * Connect wallet
8699
+ * @returns {Promise<string|null>} Wallet address or null
8700
+ */
8701
+ async connectWallet() {
8702
+ const instance = this.getInstance();
8703
+ if (instance && instance.connectWallet) {
8704
+ return await instance.connectWallet();
8705
+ }
8706
+ throw new Error('SDK not initialized. Call init() first.');
8707
+ },
8708
+
8709
+ /**
8710
+ * Check if wallet is connected
8711
+ * @returns {Promise<boolean>}
8712
+ */
8713
+ async isWalletConnected() {
8714
+ const instance = this.getInstance();
8715
+ if (instance && instance.isWalletConnected) {
8716
+ return await instance.isWalletConnected();
8717
+ }
8718
+ throw new Error('SDK not initialized. Call init() first.');
8719
+ },
8720
+
8721
+ /**
8722
+ * Update wallet info
8723
+ * @returns {Promise<any>}
8724
+ */
8725
+ async updateWalletInfo() {
8726
+ const instance = this.getInstance();
8727
+ if (instance && instance.updateWalletInfo) {
8728
+ return await instance.updateWalletInfo();
8729
+ }
8730
+ throw new Error('SDK not initialized. Call init() first.');
8731
+ },
8732
+
8733
+ /**
8734
+ * Set tracking consent
8735
+ * @param {boolean} consent - Consent value
8736
+ */
8737
+ setTrackingConsent(consent) {
8738
+ const instance = this.getInstance();
8739
+ if (instance && instance.setTrackingConsent) {
8740
+ return instance.setTrackingConsent(consent);
8741
+ }
8742
+ throw new Error('SDK not initialized. Call init() first.');
8743
+ },
8744
+
8745
+ /**
8746
+ * Get tracking consent
8747
+ * @returns {boolean}
8748
+ */
8749
+ getTrackingConsent() {
8750
+ const instance = this.getInstance();
8751
+ if (instance && instance.getTrackingConsent) {
8752
+ return instance.getTrackingConsent();
8753
+ }
8754
+ return false;
8755
+ },
8756
+
8757
+ /**
8758
+ * Get session data
8759
+ * @returns {Object}
8760
+ */
8761
+ getSessionData() {
8762
+ const instance = this.getInstance();
8763
+ if (instance && instance.getSessionData) {
8764
+ return instance.getSessionData();
8765
+ }
8766
+ return null;
8767
+ },
8768
+
8769
+ /**
8770
+ * Get chronological interactions
8771
+ * @returns {Array}
8772
+ */
8773
+ getChronologicalInteractions() {
8774
+ const instance = this.getInstance();
8775
+ if (instance && instance.getChronologicalInteractions) {
8776
+ return instance.getChronologicalInteractions();
8777
+ }
8778
+ return [];
8779
+ },
8780
+
8781
+ /**
8782
+ * Sort interactions chronologically (alias)
8783
+ * @returns {Array}
8784
+ */
8785
+ sortInteractionsChronologically() {
8786
+ const instance = this.getInstance();
8787
+ if (instance && instance.sortInteractionsChronologically) {
8788
+ return instance.sortInteractionsChronologically();
8789
+ }
8790
+ return [];
8791
+ },
8792
+
8793
+ /**
8794
+ * Enable auto events
8795
+ */
8796
+ enableAutoEvents() {
8797
+ const instance = this.getInstance();
8798
+ if (instance && instance.enableAutoEvents) {
8799
+ return instance.enableAutoEvents();
8800
+ }
8801
+ },
8802
+
8803
+ /**
8804
+ * Disable auto events
8805
+ */
8806
+ disableAutoEvents() {
8807
+ const instance = this.getInstance();
8808
+ if (instance && instance.disableAutoEvents) {
8809
+ return instance.disableAutoEvents();
8810
+ }
8811
+ },
8812
+
8813
+ /**
8814
+ * Set auto events disabled paths
8815
+ * @param {string|string[]} paths - Paths to disable
8816
+ */
8817
+ setAutoEventsDisabledPaths(paths) {
8818
+ const instance = this.getInstance();
8819
+ if (instance && instance.setAutoEventsDisabledPaths) {
8820
+ return instance.setAutoEventsDisabledPaths(paths);
8821
+ }
8822
+ },
8823
+
8824
+ /**
8825
+ * Disable specific auto events
8826
+ * @param {string|string[]} events - Event name(s) to disable
8827
+ */
8828
+ disableAutoEvent(events) {
8829
+ const instance = this.getInstance();
8830
+ if (instance && instance.disableAutoEvent) {
8831
+ return instance.disableAutoEvent(events);
8832
+ }
8833
+ },
8834
+
8835
+ /**
8836
+ * Enable specific auto events
8837
+ * @param {string|string[]} events - Event name(s) to enable
8838
+ */
8839
+ enableAutoEvent(events) {
8840
+ const instance = this.getInstance();
8841
+ if (instance && instance.enableAutoEvent) {
8842
+ return instance.enableAutoEvent(events);
8843
+ }
8844
+ },
8845
+
8846
+ /**
8847
+ * Set auto events disabled events
8848
+ * @param {string[]} events - Array of event names to disable
8849
+ */
8850
+ setAutoEventsDisabledEvents(events) {
8851
+ const instance = this.getInstance();
8852
+ if (instance && instance.setAutoEventsDisabledEvents) {
8853
+ return instance.setAutoEventsDisabledEvents(events);
8854
+ }
8855
+ },
8856
+
8857
+ /**
8858
+ * Get available auto events
8859
+ * @returns {string[]}
8860
+ */
8861
+ getAvailableAutoEvents() {
8862
+ const instance = this.getInstance();
8863
+ if (instance && instance.getAvailableAutoEvents) {
8864
+ return instance.getAvailableAutoEvents();
8865
+ }
8866
+ return [];
8867
+ },
8868
+
8869
+ /**
8870
+ * Get auto events configuration
8871
+ * @returns {Object}
8872
+ */
8873
+ getAutoEventsConfig() {
8874
+ const instance = this.getInstance();
8875
+ if (instance && instance.getAutoEventsConfig) {
8876
+ return instance.getAutoEventsConfig();
8877
+ }
8878
+ return null;
8879
+ },
8880
+
8881
+ /**
8882
+ * People object for managing user properties
8883
+ */
8884
+ get people() {
8885
+ const instance = this.getInstance();
8886
+ if (instance && instance.people) {
8887
+ return instance.people;
8888
+ }
8889
+ // Return a stub object that will work once SDK is initialized
8890
+ return {
8891
+ set: async (properties) => {
8892
+ const inst = this.getInstance();
8893
+ if (inst && inst.people && inst.people.set) {
8894
+ return await inst.people.set(properties);
8895
+ }
8896
+ throw new Error('SDK not initialized. Call init() first.');
8897
+ },
8898
+ setOnce: async (properties) => {
8899
+ const inst = this.getInstance();
8900
+ if (inst && inst.people && inst.people.setOnce) {
8901
+ return await inst.people.setOnce(properties);
8902
+ }
8903
+ throw new Error('SDK not initialized. Call init() first.');
8904
+ },
8905
+ unset: async (properties) => {
8906
+ const inst = this.getInstance();
8907
+ if (inst && inst.people && inst.people.unset) {
8908
+ return await inst.people.unset(properties);
8909
+ }
8910
+ throw new Error('SDK not initialized. Call init() first.');
8911
+ },
8912
+ increment: async (key, amount) => {
8913
+ const inst = this.getInstance();
8914
+ if (inst && inst.people && inst.people.increment) {
8915
+ return await inst.people.increment(key, amount);
8916
+ }
8917
+ throw new Error('SDK not initialized. Call init() first.');
8918
+ },
8919
+ append: async (key, values) => {
8920
+ const inst = this.getInstance();
8921
+ if (inst && inst.people && inst.people.append) {
8922
+ return await inst.people.append(key, values);
8923
+ }
8924
+ throw new Error('SDK not initialized. Call init() first.');
8925
+ },
8926
+ union: async (key, values) => {
8927
+ const inst = this.getInstance();
8928
+ if (inst && inst.people && inst.people.union) {
8929
+ return await inst.people.union(key, values);
8930
+ }
8931
+ throw new Error('SDK not initialized. Call init() first.');
8932
+ },
8933
+ remove: async (key, values) => {
8934
+ const inst = this.getInstance();
8935
+ if (inst && inst.people && inst.people.remove) {
8936
+ return await inst.people.remove(key, values);
8937
+ }
8938
+ throw new Error('SDK not initialized. Call init() first.');
8939
+ },
8940
+ trackCharge: async (amount, properties) => {
8941
+ const inst = this.getInstance();
8942
+ if (inst && inst.people && inst.people.trackCharge) {
8943
+ return await inst.people.trackCharge(amount, properties);
8944
+ }
8945
+ throw new Error('SDK not initialized. Call init() first.');
8946
+ },
8947
+ clearCharges: async () => {
8948
+ const inst = this.getInstance();
8949
+ if (inst && inst.people && inst.people.clearCharges) {
8950
+ return await inst.people.clearCharges();
8951
+ }
8952
+ throw new Error('SDK not initialized. Call init() first.');
8953
+ },
8954
+ deleteUser: async () => {
8955
+ const inst = this.getInstance();
8956
+ if (inst && inst.people && inst.people.deleteUser) {
8957
+ return await inst.people.deleteUser();
8958
+ }
8959
+ throw new Error('SDK not initialized. Call init() first.');
8960
+ }
8961
+ };
8962
+ },
8963
+
8964
+ // -------------------------------------------------------------------------
8965
+ // Group Methods
8966
+ // -------------------------------------------------------------------------
8967
+
8968
+ /**
8969
+ * Set (overwrite) the user's group membership for a given key.
8970
+ * @param {string} groupKey - The group type key (e.g. 'company_id')
8971
+ * @param {string|string[]} groupId - The group ID(s) to assign
8972
+ * @returns {Promise<Object>}
8973
+ */
8974
+ async set_group(groupKey, groupId) {
8975
+ const instance = this.getInstance();
8976
+ if (instance && instance.set_group) {
8977
+ return await instance.set_group(groupKey, groupId);
8978
+ }
8979
+ throw new Error('SDK not initialized. Call init() first.');
8980
+ },
8981
+
8982
+ /**
8983
+ * Add a group ID to an existing group key without removing current memberships.
8984
+ * @param {string} groupKey - The group type key (e.g. 'company_id')
8985
+ * @param {string} groupId - The single group ID to add
8986
+ * @returns {Promise<Object>}
8987
+ */
8988
+ async add_group(groupKey, groupId) {
8989
+ const instance = this.getInstance();
8990
+ if (instance && instance.add_group) {
8991
+ return await instance.add_group(groupKey, groupId);
8992
+ }
8993
+ throw new Error('SDK not initialized. Call init() first.');
8994
+ },
8995
+
8996
+ /**
8997
+ * Remove a specific group ID from the user's group membership.
8998
+ * @param {string} groupKey - The group type key (e.g. 'company_id')
8999
+ * @param {string} groupId - The group ID to remove
9000
+ * @returns {Promise<Object>}
9001
+ */
9002
+ async remove_group(groupKey, groupId) {
9003
+ const instance = this.getInstance();
9004
+ if (instance && instance.remove_group) {
9005
+ return await instance.remove_group(groupKey, groupId);
9006
+ }
9007
+ throw new Error('SDK not initialized. Call init() first.');
9008
+ },
9009
+
9010
+ /**
9011
+ * Get a group profile reference object for performing profile operations.
9012
+ *
9013
+ * Returns a synchronous object with the following methods:
9014
+ * .set(properties) – Set group profile properties
9015
+ * .set_once(properties) – Set properties only if not already set
9016
+ * .union(listName, values) – Add values to a list property (no duplicates)
9017
+ * .remove(listName, value) – Remove a value from a list property
9018
+ * .unset(property) – Remove a property from the group profile
9019
+ * .increment(property, value) Increment a numeric group property (default +1)
9020
+ * .append(property, value) – Append a value to a list property on the group
9021
+ * .delete() – Delete the entire group profile
9022
+ *
9023
+ * @param {string} groupKey - The group type key (e.g. 'company_id')
9024
+ * @param {string} groupId - The specific group ID
9025
+ * @returns {Object} Group profile reference object
9026
+ *
9027
+ * @example
9028
+ * const group = Cryptique.get_group('company', 'acme-corp');
9029
+ * await group.set({ plan: 'enterprise', employees: 500 });
9030
+ * await group.set_once({ created_at: new Date().toISOString() });
9031
+ * await group.union('tags', ['b2b', 'saas']);
9032
+ * await group.unset('old_property');
9033
+ * await group.delete();
9034
+ */
9035
+ get_group(groupKey, groupId) {
9036
+ const instance = this.getInstance();
9037
+ if (instance && instance.get_group) {
9038
+ return instance.get_group(groupKey, groupId);
9039
+ }
9040
+ // Return a stub whose methods all throw if SDK not yet ready
9041
+ const notReady = () => { throw new Error('SDK not initialized. Call init() first.'); };
9042
+ return {
9043
+ set: notReady,
9044
+ set_once: notReady,
9045
+ union: notReady,
9046
+ remove: notReady,
9047
+ unset: notReady,
9048
+ increment: notReady,
9049
+ append: notReady,
9050
+ delete: notReady
9051
+ };
9052
+ }
9053
+ };
9054
+
9055
+ // Proxy all methods from window.Cryptique to our export
9056
+ // This will be populated after script.js loads
9057
+ // Also sync properties that might not be methods
9058
+ const syncMethods = () => {
9059
+ if (typeof window !== 'undefined' && window.Cryptique) {
9060
+ Object.keys(window.Cryptique).forEach(key => {
9061
+ // Skip if we already have a custom implementation
9062
+ if (['people', 'set_group', 'add_group', 'remove_group', 'get_group'].includes(key) || CryptiqueSDK.hasOwnProperty(key)) {
9063
+ return;
9064
+ }
9065
+
9066
+ if (typeof window.Cryptique[key] === 'function') {
9067
+ CryptiqueSDK[key] = window.Cryptique[key].bind(window.Cryptique);
9068
+ } else {
9069
+ CryptiqueSDK[key] = window.Cryptique[key];
9070
+ }
9071
+ });
9072
+
9073
+ // Sync version and siteId properties
9074
+ if (window.Cryptique.version) {
9075
+ CryptiqueSDK.version = window.Cryptique.version;
9076
+ }
9077
+ if (window.Cryptique.siteId) {
9078
+ CryptiqueSDK.siteId = window.Cryptique.siteId;
9079
+ }
9080
+ if (window.Cryptique.sessionData) {
9081
+ CryptiqueSDK.sessionData = window.Cryptique.sessionData;
9082
+ }
9083
+ }
9084
+ };
9085
+
9086
+ // Try to sync immediately if SDK is already loaded
9087
+ if (typeof window !== 'undefined') {
9088
+ syncMethods();
9089
+
9090
+ // Also sync after DOM loads (in case script loads async)
9091
+ if (window.addEventListener) {
9092
+ window.addEventListener('load', syncMethods);
9093
+ if (document.readyState === 'loading') {
9094
+ document.addEventListener('DOMContentLoaded', syncMethods);
9095
+ } else {
9096
+ syncMethods();
9097
+ }
9098
+ }
9099
+ }
9100
+
9101
+ // Export for CommonJS
9102
+ if (typeof module !== 'undefined' && module.exports) {
9103
+ module.exports = CryptiqueSDK;
9104
+ module.exports.default = CryptiqueSDK;
9170
9105
  }
9171
9106
 
9172
9107
  return CryptiqueSDK;