posthog-js 1.29.3 → 1.31.0

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/es.js CHANGED
@@ -881,7 +881,7 @@ var LZString = {
881
881
  }
882
882
  };
883
883
 
884
- var version = "1.29.3";
884
+ var version = "1.31.0";
885
885
 
886
886
  // e.g. Config.DEBUG = Config.DEBUG || instance.get_config('debug')
887
887
 
@@ -3290,6 +3290,7 @@ var PostHogFeatureFlags = /*#__PURE__*/function () {
3290
3290
  }, {
3291
3291
  key: "receivedFeatureFlags",
3292
3292
  value: function receivedFeatureFlags(response) {
3293
+ this.instance.decideEndpointWasHit = true;
3293
3294
  parseFeatureFlagDecideResponse(response, this.instance.persistence);
3294
3295
  var flags = this.getFlags();
3295
3296
  var variants = this.getFlagVariants();
@@ -3967,8 +3968,9 @@ var Decide = /*#__PURE__*/function () {
3967
3968
  function Decide(instance) {
3968
3969
  _classCallCheck(this, Decide);
3969
3970
 
3970
- this.instance = instance;
3971
- this.instance.decideEndpointWasHit = false;
3971
+ this.instance = instance; // don't need to wait for `decide` to return if flags were provided on initialisation
3972
+
3973
+ this.instance.decideEndpointWasHit = this.instance._hasBootstrappedFeatureFlags();
3972
3974
  }
3973
3975
 
3974
3976
  _createClass(Decide, [{
@@ -5543,12 +5545,28 @@ var SessionIdManager = /*#__PURE__*/function () {
5543
5545
  this._sessionId = undefined;
5544
5546
  this._sessionStartTimestamp = null;
5545
5547
  this._sessionActivityTimestamp = null;
5548
+ var persistenceName = config['persistence_name'] || config['token'];
5549
+ this.window_id_storage_key = 'ph_' + persistenceName + '_window_id';
5550
+ this.primary_window_exists_storage_key = 'ph_' + persistenceName + '_primary_window_exists'; // primary_window_exists is set when the DOM has been loaded and is cleared on unload
5551
+ // if it exists here it means there was no unload which suggests this window is opened as a tab duplication, window.open, etc.
5552
+
5553
+ if (!this.persistence.disabled && sessionStore.is_supported()) {
5554
+ var lastWindowId = sessionStore.parse(this.window_id_storage_key);
5555
+ var primaryWindowExists = sessionStore.parse(this.primary_window_exists_storage_key);
5556
+
5557
+ if (lastWindowId && !primaryWindowExists) {
5558
+ // Persist window from previous storage state
5559
+ this._windowId = lastWindowId;
5560
+ } else {
5561
+ // Wipe any reference to previous window id
5562
+ sessionStore.remove(this.window_id_storage_key);
5563
+ } // Flag this session as having a primary window
5546
5564
 
5547
- if (config['persistence_name']) {
5548
- this.window_id_storage_key = 'ph_' + config['persistence_name'] + '_window_id';
5549
- } else {
5550
- this.window_id_storage_key = 'ph_' + config['token'] + '_window_id';
5565
+
5566
+ sessionStore.set(this.primary_window_exists_storage_key, true);
5551
5567
  }
5568
+
5569
+ this._listenToReloadWindow();
5552
5570
  } // Note: this tries to store the windowId in sessionStorage. SessionStorage is unique to the current window/tab,
5553
5571
  // and persists page loads/reloads. So it's uniquely suited for storing the windowId. This function also respects
5554
5572
  // when persistence is disabled (by user config) and when sessionStorage is not supported (it *should* be supported on all browsers),
@@ -5575,7 +5593,8 @@ var SessionIdManager = /*#__PURE__*/function () {
5575
5593
 
5576
5594
  if (!this.persistence.disabled && sessionStore.is_supported()) {
5577
5595
  return sessionStore.parse(this.window_id_storage_key);
5578
- }
5596
+ } // New window id will be generated
5597
+
5579
5598
 
5580
5599
  return null;
5581
5600
  } // Note: 'this.persistence.register' can be disabled in the config.
@@ -5614,6 +5633,24 @@ var SessionIdManager = /*#__PURE__*/function () {
5614
5633
  value: function resetSessionId() {
5615
5634
  this._setSessionId(null, null, null);
5616
5635
  }
5636
+ /*
5637
+ * Listens to window unloads and removes the primaryWindowExists key from sessionStorage.
5638
+ * Reloaded or fresh tabs created after a DOM unloads (reloading the same tab) WILL NOT have this primaryWindowExists flag in session storage.
5639
+ * Cloned sessions (new tab, tab duplication, window.open(), ...) WILL have this primaryWindowExists flag in their copied session storage.
5640
+ * We conditionally check the primaryWindowExists value in the constructor to decide if the window id in the last session storage should be carried over.
5641
+ */
5642
+
5643
+ }, {
5644
+ key: "_listenToReloadWindow",
5645
+ value: function _listenToReloadWindow() {
5646
+ var _this = this;
5647
+
5648
+ window.addEventListener('beforeunload', function () {
5649
+ if (!_this.persistence.disabled && sessionStore.is_supported()) {
5650
+ sessionStore.remove(_this.primary_window_exists_storage_key);
5651
+ }
5652
+ });
5653
+ }
5617
5654
  /*
5618
5655
  * This function returns the current sessionId and windowId. It should be used to
5619
5656
  * access these values over directly calling `._sessionId` or `._windowId`. In addition
@@ -5824,6 +5861,8 @@ var SentryIntegration = /*#__PURE__*/_createClass(function SentryIntegration(_po
5824
5861
 
5825
5862
  this.setupOnce = function (addGlobalEventProcessor) {
5826
5863
  addGlobalEventProcessor(function (event) {
5864
+ var _event$exception, _exceptions$, _exceptions$2;
5865
+
5827
5866
  if (event.level !== 'error' || !_posthog.__loaded) return event;
5828
5867
  if (!event.tags) event.tags = {};
5829
5868
  event.tags['PostHog Person URL'] = _posthog.config.api_host + '/person/' + _posthog.get_distinct_id();
@@ -5832,9 +5871,13 @@ var SentryIntegration = /*#__PURE__*/_createClass(function SentryIntegration(_po
5832
5871
  event.tags['PostHog Recording URL'] = _posthog.config.api_host + '/recordings/#sessionRecordingId=' + _posthog.sessionManager.checkAndGetSessionAndWindowId(true).sessionId;
5833
5872
  }
5834
5873
 
5874
+ var exceptions = ((_event$exception = event.exception) === null || _event$exception === void 0 ? void 0 : _event$exception.values) || [];
5835
5875
  var data = {
5836
5876
  $sentry_event_id: event.event_id,
5837
- $sentry_exception: event.exception
5877
+ $sentry_exception: event.exception,
5878
+ $sentry_exception_message: (_exceptions$ = exceptions[0]) === null || _exceptions$ === void 0 ? void 0 : _exceptions$.value,
5879
+ $sentry_exception_type: (_exceptions$2 = exceptions[0]) === null || _exceptions$2 === void 0 ? void 0 : _exceptions$2.type,
5880
+ $sentry_tags: event.tags
5838
5881
  };
5839
5882
  if (organization && projectId) data['$sentry_url'] = (prefix || 'https://sentry.io/organizations/') + organization + '/issues/?project=' + projectId + '&query=' + event.event_id;
5840
5883
 
@@ -5954,7 +5997,8 @@ var defaultConfig = function defaultConfig() {
5954
5997
  _capture_metrics: false,
5955
5998
  _capture_performance: false,
5956
5999
  name: 'posthog',
5957
- callback_fn: 'posthog._jsc'
6000
+ callback_fn: 'posthog._jsc',
6001
+ bootstrap: {}
5958
6002
  };
5959
6003
  };
5960
6004
  /**
@@ -6103,6 +6147,8 @@ var PostHog = /*#__PURE__*/function () {
6103
6147
  }, {
6104
6148
  key: "_init",
6105
6149
  value: function _init(token) {
6150
+ var _config$bootstrap;
6151
+
6106
6152
  var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6107
6153
  var name = arguments.length > 2 ? arguments[2] : undefined;
6108
6154
  this.__loaded = true;
@@ -6127,14 +6173,43 @@ var PostHog = /*#__PURE__*/function () {
6127
6173
 
6128
6174
  this._gdpr_init();
6129
6175
 
6176
+ if (((_config$bootstrap = config.bootstrap) === null || _config$bootstrap === void 0 ? void 0 : _config$bootstrap.distinctID) !== undefined) {
6177
+ var _config$bootstrap2;
6178
+
6179
+ var uuid = this.get_config('get_device_id')(_UUID());
6180
+ var deviceID = (_config$bootstrap2 = config.bootstrap) !== null && _config$bootstrap2 !== void 0 && _config$bootstrap2.isIdentifiedID ? uuid : config.bootstrap.distinctID;
6181
+ this.register({
6182
+ distinct_id: config.bootstrap.distinctID,
6183
+ $device_id: deviceID
6184
+ });
6185
+ }
6186
+
6187
+ if (this._hasBootstrappedFeatureFlags()) {
6188
+ var _config$bootstrap3;
6189
+
6190
+ var activeFlags = Object.keys(((_config$bootstrap3 = config.bootstrap) === null || _config$bootstrap3 === void 0 ? void 0 : _config$bootstrap3.featureFlags) || {}).filter(function (flag) {
6191
+ var _config$bootstrap4, _config$bootstrap4$fe;
6192
+
6193
+ return !!((_config$bootstrap4 = config.bootstrap) !== null && _config$bootstrap4 !== void 0 && (_config$bootstrap4$fe = _config$bootstrap4.featureFlags) !== null && _config$bootstrap4$fe !== void 0 && _config$bootstrap4$fe[flag]);
6194
+ }).reduce(function (res, key) {
6195
+ var _config$bootstrap5, _config$bootstrap5$fe;
6196
+
6197
+ return res[key] = ((_config$bootstrap5 = config.bootstrap) === null || _config$bootstrap5 === void 0 ? void 0 : (_config$bootstrap5$fe = _config$bootstrap5.featureFlags) === null || _config$bootstrap5$fe === void 0 ? void 0 : _config$bootstrap5$fe[key]) || false, res;
6198
+ }, {});
6199
+ this.featureFlags.receivedFeatureFlags({
6200
+ featureFlags: activeFlags
6201
+ });
6202
+ }
6203
+
6130
6204
  if (!this.get_distinct_id()) {
6131
6205
  // There is no need to set the distinct id
6132
6206
  // or the device id if something was already stored
6133
6207
  // in the persitence
6134
- var uuid = this.get_config('get_device_id')(_UUID());
6208
+ var _uuid = this.get_config('get_device_id')(_UUID());
6209
+
6135
6210
  this.register_once({
6136
- distinct_id: uuid,
6137
- $device_id: uuid
6211
+ distinct_id: _uuid,
6212
+ $device_id: _uuid
6138
6213
  }, '');
6139
6214
  } // Set up event handler for pageleave
6140
6215
  // Use `onpagehide` if available, see https://calendar.perfplanet.com/2020/beaconing-in-practice/#beaconing-reliability-avoiding-abandons
@@ -6415,6 +6490,13 @@ var PostHog = /*#__PURE__*/function () {
6415
6490
  execute(other_calls, this);
6416
6491
  execute(capturing_calls, this);
6417
6492
  }
6493
+ }, {
6494
+ key: "_hasBootstrappedFeatureFlags",
6495
+ value: function _hasBootstrappedFeatureFlags() {
6496
+ var _this$config$bootstra, _this$config$bootstra2;
6497
+
6498
+ return ((_this$config$bootstra = this.config.bootstrap) === null || _this$config$bootstra === void 0 ? void 0 : _this$config$bootstra.featureFlags) && Object.keys((_this$config$bootstra2 = this.config.bootstrap) === null || _this$config$bootstra2 === void 0 ? void 0 : _this$config$bootstra2.featureFlags).length > 0 || false;
6499
+ }
6418
6500
  /**
6419
6501
  * push() keeps the standard async-array-push
6420
6502
  * behavior around after the lib is loaded.