@leanbase-giangnd/js 0.2.2 → 0.2.3

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.
@@ -2846,7 +2846,7 @@ var leanbase = (function () {
2846
2846
  }
2847
2847
  };
2848
2848
 
2849
- var version = "0.2.2";
2849
+ var version = "0.2.3";
2850
2850
  var packageInfo = {
2851
2851
  version: version};
2852
2852
 
@@ -6707,6 +6707,11 @@ var leanbase = (function () {
6707
6707
  });
6708
6708
  this._makeSamplingDecision(this.sessionId);
6709
6709
  await this._startRecorder();
6710
+ // If rrweb failed to load/start, do not proceed further.
6711
+ // This prevents installing listeners that assume rrweb is active.
6712
+ if (!this.isStarted) {
6713
+ return;
6714
+ }
6710
6715
  // calling addEventListener multiple times is safe and will not add duplicates
6711
6716
  addEventListener(win, 'beforeunload', this._onBeforeUnload);
6712
6717
  addEventListener(win, 'offline', this._onOffline);
@@ -7240,13 +7245,19 @@ var leanbase = (function () {
7240
7245
  }
7241
7246
  });
7242
7247
  const activePlugins = this._gatherRRWebPlugins();
7243
- this._stopRrweb = rrwebRecord({
7244
- emit: event => {
7245
- this.onRRwebEmit(event);
7246
- },
7247
- plugins: activePlugins,
7248
- ...sessionRecordingOptions
7249
- });
7248
+ try {
7249
+ this._stopRrweb = rrwebRecord({
7250
+ emit: event => {
7251
+ this.onRRwebEmit(event);
7252
+ },
7253
+ plugins: activePlugins,
7254
+ ...sessionRecordingOptions
7255
+ });
7256
+ } catch (e) {
7257
+ logger.error('failed to start rrweb recorder', e);
7258
+ this._stopRrweb = undefined;
7259
+ return;
7260
+ }
7250
7261
  // We reset the last activity timestamp, resetting the idle timer
7251
7262
  this._lastActivityTimestamp = Date.now();
7252
7263
  // stay unknown if we're not sure if we're idle or not
@@ -7432,18 +7443,25 @@ var leanbase = (function () {
7432
7443
  // If extensions provide an init function, use it. Otherwise, fall back to the local LazyLoadedSessionRecording
7433
7444
  if (assignableWindow.__PosthogExtensions__?.initSessionRecording) {
7434
7445
  if (!this._lazyLoadedSessionRecording) {
7435
- this._lazyLoadedSessionRecording = assignableWindow.__PosthogExtensions__?.initSessionRecording(this._instance);
7436
- this._lazyLoadedSessionRecording._forceAllowLocalhostNetworkCapture = this._forceAllowLocalhostNetworkCapture;
7446
+ const maybeRecording = assignableWindow.__PosthogExtensions__?.initSessionRecording(this._instance);
7447
+ if (maybeRecording && typeof maybeRecording.start === 'function') {
7448
+ this._lazyLoadedSessionRecording = maybeRecording;
7449
+ this._lazyLoadedSessionRecording._forceAllowLocalhostNetworkCapture = this._forceAllowLocalhostNetworkCapture;
7450
+ } else {
7451
+ log.warn('initSessionRecording was present but did not return a recorder instance; falling back to local recorder');
7452
+ }
7437
7453
  }
7438
- try {
7439
- const maybePromise = this._lazyLoadedSessionRecording.start(startReason);
7440
- if (maybePromise && typeof maybePromise.catch === 'function') {
7441
- maybePromise.catch(e => logger$2.error('error starting session recording', e));
7454
+ if (this._lazyLoadedSessionRecording) {
7455
+ try {
7456
+ const maybePromise = this._lazyLoadedSessionRecording.start(startReason);
7457
+ if (maybePromise && typeof maybePromise.catch === 'function') {
7458
+ maybePromise.catch(e => logger$2.error('error starting session recording', e));
7459
+ }
7460
+ } catch (e) {
7461
+ logger$2.error('error starting session recording', e);
7442
7462
  }
7443
- } catch (e) {
7444
- logger$2.error('error starting session recording', e);
7463
+ return;
7445
7464
  }
7446
- return;
7447
7465
  }
7448
7466
  if (!this._lazyLoadedSessionRecording) {
7449
7467
  this._lazyLoadedSessionRecording = new LazyLoadedSessionRecording(this._instance);
@@ -7558,6 +7576,10 @@ var leanbase = (function () {
7558
7576
  token
7559
7577
  });
7560
7578
  super(token, mergedConfig);
7579
+ this._remoteConfigLoadAttempted = false;
7580
+ this._remoteConfigResolved = false;
7581
+ this._featureFlagsResolved = false;
7582
+ this._maybeStartedSessionRecording = false;
7561
7583
  this.personProcessingSetOncePropertiesSent = false;
7562
7584
  this.isLoaded = false;
7563
7585
  this.config = mergedConfig;
@@ -7581,10 +7603,20 @@ var leanbase = (function () {
7581
7603
  this.replayAutocapture.startIfEnabled();
7582
7604
  if (this.sessionManager && this.config.cookieless_mode !== 'always') {
7583
7605
  this.sessionRecording = new SessionRecording(this);
7584
- this.sessionRecording.startIfEnabledOrStop();
7585
7606
  }
7607
+ // Start session recording only once flags + remote config have been resolved.
7608
+ // This matches the PostHog browser SDK where replay activation is driven by remote config and flags.
7586
7609
  if (this.config.preloadFeatureFlags !== false) {
7587
- this.reloadFeatureFlags();
7610
+ this.reloadFeatureFlags({
7611
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
7612
+ cb: _err => {
7613
+ this._featureFlagsResolved = true;
7614
+ this._maybeStartSessionRecording();
7615
+ }
7616
+ });
7617
+ } else {
7618
+ // If feature flags preload is explicitly disabled, treat this requirement as satisfied.
7619
+ this._featureFlagsResolved = true;
7588
7620
  }
7589
7621
  this.config.loaded?.(this);
7590
7622
  if (this.config.capture_pageview) {
@@ -7594,9 +7626,26 @@ var leanbase = (function () {
7594
7626
  }
7595
7627
  }, 1);
7596
7628
  }
7597
- addEventListener(document$1, 'DOMContentLoaded', () => {
7598
- this.loadRemoteConfig();
7599
- });
7629
+ const triggerRemoteConfigLoad = reason => {
7630
+ logger$2.info(`remote config load triggered via ${reason}`);
7631
+ void this.loadRemoteConfig();
7632
+ };
7633
+ if (document$1) {
7634
+ if (document$1.readyState === 'loading') {
7635
+ logger$2.info('remote config load deferred until DOMContentLoaded');
7636
+ const onDomReady = () => {
7637
+ document$1?.removeEventListener('DOMContentLoaded', onDomReady);
7638
+ triggerRemoteConfigLoad('dom');
7639
+ };
7640
+ addEventListener(document$1, 'DOMContentLoaded', onDomReady, {
7641
+ once: true
7642
+ });
7643
+ } else {
7644
+ triggerRemoteConfigLoad('immediate');
7645
+ }
7646
+ } else {
7647
+ triggerRemoteConfigLoad('no-document');
7648
+ }
7600
7649
  addEventListener(window, 'onpagehide' in self ? 'pagehide' : 'unload', this.capturePageLeave.bind(this), {
7601
7650
  passive: false
7602
7651
  });
@@ -7633,11 +7682,19 @@ var leanbase = (function () {
7633
7682
  }
7634
7683
  }
7635
7684
  async loadRemoteConfig() {
7636
- if (!this.isRemoteConfigLoaded) {
7685
+ if (this._remoteConfigLoadAttempted) {
7686
+ return;
7687
+ }
7688
+ this._remoteConfigLoadAttempted = true;
7689
+ try {
7637
7690
  const remoteConfig = await this.reloadRemoteConfigAsync();
7638
7691
  if (remoteConfig) {
7639
7692
  this.onRemoteConfig(remoteConfig);
7640
7693
  }
7694
+ } finally {
7695
+ // Regardless of success/failure, we consider remote config "resolved" so replay isn't blocked forever.
7696
+ this._remoteConfigResolved = true;
7697
+ this._maybeStartSessionRecording();
7641
7698
  }
7642
7699
  }
7643
7700
  onRemoteConfig(config) {
@@ -7650,6 +7707,26 @@ var leanbase = (function () {
7650
7707
  this.isRemoteConfigLoaded = true;
7651
7708
  this.replayAutocapture?.onRemoteConfig(config);
7652
7709
  this.sessionRecording?.onRemoteConfig(config);
7710
+ // Remote config has been applied; allow replay start if flags are also ready.
7711
+ this._remoteConfigResolved = true;
7712
+ this._maybeStartSessionRecording();
7713
+ }
7714
+ _maybeStartSessionRecording() {
7715
+ if (this._maybeStartedSessionRecording) {
7716
+ return;
7717
+ }
7718
+ if (!this.sessionRecording) {
7719
+ return;
7720
+ }
7721
+ if (!this._featureFlagsResolved || !this._remoteConfigResolved) {
7722
+ return;
7723
+ }
7724
+ this._maybeStartedSessionRecording = true;
7725
+ try {
7726
+ this.sessionRecording.startIfEnabledOrStop();
7727
+ } catch (e) {
7728
+ logger$2.error('Failed to start session recording', e);
7729
+ }
7653
7730
  }
7654
7731
  fetch(url, options) {
7655
7732
  const fetchFn = getFetch();