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