crexperium-sdk 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -602,6 +602,82 @@ class DealsResource extends BaseResource {
602
602
  }
603
603
  }
604
604
 
605
+ /**
606
+ * Experiments API Resource
607
+ * Handles A/B testing and feature flagging
608
+ */
609
+ class ExperimentsResource extends BaseResource {
610
+ /**
611
+ * Get an experiment by ID or key
612
+ */
613
+ async get(experimentIdOrKey) {
614
+ return this.http.get(`/api/v1/experiments/${experimentIdOrKey}/`);
615
+ }
616
+ /**
617
+ * Get a variant assignment for a visitor
618
+ * This is the main SDK method for A/B testing
619
+ *
620
+ * @param experimentKey - The unique key of the experiment
621
+ * @param visitorId - The unique identifier for the visitor
622
+ * @param context - Optional context data (user agent, device, etc.)
623
+ * @returns The assigned variant with its payload
624
+ *
625
+ * @example
626
+ * ```typescript
627
+ * const assignment = await client.experiments.assign('checkout_button_test', {
628
+ * visitor_id: 'visitor_123',
629
+ * context: {
630
+ * user_agent: navigator.userAgent,
631
+ * device_type: 'desktop',
632
+ * browser: 'chrome'
633
+ * }
634
+ * });
635
+ *
636
+ * // Use the variant payload
637
+ * const buttonColor = assignment.variant.payload.button_color;
638
+ * ```
639
+ */
640
+ async assign(experimentKey, input) {
641
+ return this.http.post(`/api/v1/experiments/${experimentKey}/assign/`, input);
642
+ }
643
+ /**
644
+ * Track a conversion for a visitor in an experiment
645
+ * Call this when a visitor completes the desired action
646
+ *
647
+ * @param experimentKey - The unique key of the experiment
648
+ * @param input - Conversion data including visitor_id
649
+ *
650
+ * @example
651
+ * ```typescript
652
+ * await client.experiments.trackConversion('checkout_button_test', {
653
+ * visitor_id: 'visitor_123',
654
+ * event_name: 'purchase',
655
+ * event_properties: {
656
+ * amount: 99.99,
657
+ * currency: 'USD'
658
+ * }
659
+ * });
660
+ * ```
661
+ */
662
+ async trackConversion(experimentKey, input) {
663
+ await this.http.post(`/api/v1/experiments/${experimentKey}/convert/`, input);
664
+ }
665
+ /**
666
+ * Get a variant assignment and automatically track the exposure
667
+ * This combines assign() and exposure tracking in one call
668
+ *
669
+ * @param experimentKey - The unique key of the experiment
670
+ * @param input - Assignment data including visitor_id
671
+ * @returns The assigned variant with its payload
672
+ */
673
+ async getVariant(experimentKey, input) {
674
+ const assignment = await this.assign(experimentKey, input);
675
+ // Exposure is automatically tracked by the backend on assign
676
+ // but we return the assignment for client use
677
+ return assignment;
678
+ }
679
+ }
680
+
605
681
  /**
606
682
  * Storage utilities for browser localStorage/cookies
607
683
  */
@@ -13217,18 +13293,13 @@ class SessionReplayPlugin {
13217
13293
  */
13218
13294
  async init() {
13219
13295
  try {
13220
- console.log('[SessionReplay] Initializing session replay...');
13221
13296
  // Start session on backend
13222
13297
  await this.startSession();
13223
- console.log('[SessionReplay] Session started on backend, sessionId:', this.session?.sessionId);
13224
13298
  // Start rrweb recording
13225
- console.log('[SessionReplay] Starting rrweb recording...');
13226
13299
  this.startRrwebRecording();
13227
- console.log('[SessionReplay] rrweb recording started');
13228
13300
  // IMPORTANT: Flush initial events (Type 4 Meta + Type 2 Full Snapshot) immediately
13229
13301
  // so the session is playable right away, don't wait for the 5s flush interval
13230
13302
  setTimeout(() => {
13231
- console.log('[SessionReplay] Performing initial flush of critical events...');
13232
13303
  this.flush();
13233
13304
  }, 100); // Small delay to ensure rrweb events are captured
13234
13305
  // Intercept console methods
@@ -13303,17 +13374,9 @@ class SessionReplayPlugin {
13303
13374
  this.stopRecording = record({
13304
13375
  emit: (event) => {
13305
13376
  // Debug: Log event types
13306
- if (event.type === 4) {
13307
- console.log('[SessionReplay] Captured Meta event (type 4)');
13308
- }
13309
- else if (event.type === 2) {
13310
- console.log('[SessionReplay] Captured Full Snapshot event (type 2)');
13311
- }
13312
13377
  this.eventBuffer.push(event);
13313
- console.log(`[SessionReplay] Event buffered. Type: ${event.type}, Buffer size: ${this.eventBuffer.length}`);
13314
13378
  // Auto-flush if buffer reaches max size
13315
13379
  if (this.eventBuffer.length >= (this.config.buffering?.maxBufferSize || 100)) {
13316
- console.log('[SessionReplay] Buffer full, flushing...');
13317
13380
  this.flush();
13318
13381
  }
13319
13382
  },
@@ -13655,16 +13718,12 @@ class SessionReplayPlugin {
13655
13718
  * Flush buffered events to backend
13656
13719
  */
13657
13720
  async flush() {
13658
- console.log(`[SessionReplay] flush() called. Session: ${!!this.session}, Event buffer: ${this.eventBuffer.length}, Telemetry buffer: ${this.telemetryBuffer.length}`);
13659
13721
  if (!this.session) {
13660
- console.warn('[SessionReplay] flush() skipped - no session yet!');
13661
13722
  return;
13662
13723
  }
13663
13724
  if (this.eventBuffer.length === 0 && this.telemetryBuffer.length === 0) {
13664
- console.log('[SessionReplay] flush() skipped - buffers empty');
13665
13725
  return;
13666
13726
  }
13667
- console.log(`[SessionReplay] Flushing ${this.eventBuffer.length} events to backend...`);
13668
13727
  const eventsToSend = [...this.eventBuffer];
13669
13728
  const telemetryToSend = [...this.telemetryBuffer];
13670
13729
  // Clear buffers
@@ -13784,6 +13843,7 @@ class CRMClient {
13784
13843
  this._events = new EventsResource(this.http);
13785
13844
  this._contacts = new ContactsResource(this.http);
13786
13845
  this._deals = new DealsResource(this.http);
13846
+ this._experiments = new ExperimentsResource(this.http);
13787
13847
  // Initialize browser plugins if in browser
13788
13848
  if (isBrowser) {
13789
13849
  this.initBrowserPlugins();
@@ -13807,6 +13867,12 @@ class CRMClient {
13807
13867
  get deals() {
13808
13868
  return this._deals;
13809
13869
  }
13870
+ /**
13871
+ * Experiments resource for A/B testing and feature flags
13872
+ */
13873
+ get experiments() {
13874
+ return this._experiments;
13875
+ }
13810
13876
  /**
13811
13877
  * Visitor ID plugin (browser only)
13812
13878
  */
@@ -13870,7 +13936,7 @@ class CRMClient {
13870
13936
  */
13871
13937
  // Main client
13872
13938
  // Version
13873
- const VERSION = '1.1.0';
13939
+ const VERSION = '1.2.5';
13874
13940
 
13875
- export { AuthenticationError, AutoPageViewPlugin, CRMClient, CRMError, Config, ConsoleLevel, ContactsResource, DealsResource, DeviceInfoPlugin, EventsResource, NetworkError, RateLimitError, ResourceNotFoundError, ServerError, SessionEventType, SessionReplayPlugin, VERSION, ValidationError, VisitorIdPlugin, detectBrowser, detectDeviceType, detectOS, generateUUID, getDeviceInfo, getLocalStorageItem, isLocalStorageAvailable, removeLocalStorageItem, setLocalStorageItem };
13941
+ export { AuthenticationError, AutoPageViewPlugin, CRMClient, CRMError, Config, ConsoleLevel, ContactsResource, DealsResource, DeviceInfoPlugin, EventsResource, ExperimentsResource, NetworkError, RateLimitError, ResourceNotFoundError, ServerError, SessionEventType, SessionReplayPlugin, VERSION, ValidationError, VisitorIdPlugin, detectBrowser, detectDeviceType, detectOS, generateUUID, getDeviceInfo, getLocalStorageItem, isLocalStorageAvailable, removeLocalStorageItem, setLocalStorageItem };
13876
13942
  //# sourceMappingURL=index.mjs.map