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