posthog-js-lite 2.2.1 → 2.4.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/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # 2.4.0 - 2023-04-20
2
+
3
+ 1. Fixes a race condition that could occur when initialising PostHog
4
+ 2. Fixes an issue where feature flags would not be reloaded after a reset
5
+
6
+ # 2.3.0 - 2023-04-19
7
+
8
+ 1. Some small fixes to incorrect types
9
+ 2. Fixed fetch compatibility by aligning error handling
10
+ 3. Added two errors: PostHogFetchHttpError (non-2xx status) and PostHogFetchNetworkError (fetch network error)
11
+ 4. Added .on('error', (err) => void)
12
+ 5. shutdownAsync now ignores fetch errors. They should be handled with .on('error', ...) from now on.
13
+
1
14
  # 2.2.1 - 2023-02-13
2
15
 
3
16
  1. Fixes an issue where background network errors would trigger unhandled promise warnings
package/lib/index.cjs.js CHANGED
@@ -180,29 +180,31 @@ function retriable(fn, props) {
180
180
  i = 0;
181
181
  _d.label = 1;
182
182
  case 1:
183
- if (!(i < retryCount + 1)) return [3 /*break*/, 8];
184
- _d.label = 2;
183
+ if (!(i < retryCount + 1)) return [3 /*break*/, 7];
184
+ if (!(i > 0)) return [3 /*break*/, 3];
185
+ // don't wait when it's the last try
186
+ return [4 /*yield*/, new Promise(function (r) { return setTimeout(r, retryDelay); })];
185
187
  case 2:
186
- _d.trys.push([2, 4, , 5]);
187
- return [4 /*yield*/, fn()];
188
+ // don't wait when it's the last try
189
+ _d.sent();
190
+ _d.label = 3;
188
191
  case 3:
192
+ _d.trys.push([3, 5, , 6]);
193
+ return [4 /*yield*/, fn()];
194
+ case 4:
189
195
  res = _d.sent();
190
196
  return [2 /*return*/, res];
191
- case 4:
197
+ case 5:
192
198
  e_1 = _d.sent();
193
199
  lastError = e_1;
194
200
  if (!retryCheck(e_1)) {
195
201
  throw e_1;
196
202
  }
197
- return [3 /*break*/, 5];
198
- case 5: return [4 /*yield*/, new Promise(function (r) { return setTimeout(r, retryDelay); })];
203
+ return [3 /*break*/, 6];
199
204
  case 6:
200
- _d.sent();
201
- _d.label = 7;
202
- case 7:
203
205
  i++;
204
206
  return [3 /*break*/, 1];
205
- case 8: throw lastError;
207
+ case 7: throw lastError;
206
208
  }
207
209
  });
208
210
  });
@@ -701,9 +703,35 @@ var SimpleEventEmitter = /** @class */ (function () {
701
703
  return SimpleEventEmitter;
702
704
  }());
703
705
 
706
+ var PostHogFetchHttpError = /** @class */ (function (_super) {
707
+ __extends(PostHogFetchHttpError, _super);
708
+ function PostHogFetchHttpError(response) {
709
+ var _this = _super.call(this, 'HTTP error while fetching PostHog: ' + response.status) || this;
710
+ _this.response = response;
711
+ _this.name = 'PostHogFetchHttpError';
712
+ return _this;
713
+ }
714
+ return PostHogFetchHttpError;
715
+ }(Error));
716
+ var PostHogFetchNetworkError = /** @class */ (function (_super) {
717
+ __extends(PostHogFetchNetworkError, _super);
718
+ function PostHogFetchNetworkError(error) {
719
+ var _this = _super.call(this, 'Network error while fetching PostHog', error instanceof Error ? { cause: error } : {}) || this;
720
+ _this.error = error;
721
+ _this.name = 'PostHogFetchNetworkError';
722
+ return _this;
723
+ }
724
+ return PostHogFetchNetworkError;
725
+ }(Error));
726
+ function isPostHogFetchError(err) {
727
+ return typeof err === 'object' && (err.name === 'PostHogFetchHttpError' || err.name === 'PostHogFetchNetworkError');
728
+ }
704
729
  var PostHogCoreStateless = /** @class */ (function () {
705
730
  function PostHogCoreStateless(apiKey, options) {
706
- var _a, _b, _c, _d;
731
+ var _a, _b, _c, _d, _e;
732
+ this.debugMode = false;
733
+ this.pendingPromises = {};
734
+ this.disableGeoip = true;
707
735
  // internal
708
736
  this._events = new SimpleEventEmitter();
709
737
  assert(apiKey, "You must pass your PostHog project's api key.");
@@ -717,8 +745,10 @@ var PostHogCoreStateless = /** @class */ (function () {
717
745
  this._retryOptions = {
718
746
  retryCount: (_b = options === null || options === void 0 ? void 0 : options.fetchRetryCount) !== null && _b !== void 0 ? _b : 3,
719
747
  retryDelay: (_c = options === null || options === void 0 ? void 0 : options.fetchRetryDelay) !== null && _c !== void 0 ? _c : 3000,
748
+ retryCheck: isPostHogFetchError,
720
749
  };
721
750
  this.requestTimeout = (_d = options === null || options === void 0 ? void 0 : options.requestTimeout) !== null && _d !== void 0 ? _d : 10000; // 10 seconds
751
+ this.disableGeoip = (_e = options === null || options === void 0 ? void 0 : options.disableGeoip) !== null && _e !== void 0 ? _e : true;
722
752
  }
723
753
  PostHogCoreStateless.prototype.getCommonEventProperties = function () {
724
754
  return {
@@ -747,6 +777,7 @@ var PostHogCoreStateless = /** @class */ (function () {
747
777
  var _a;
748
778
  if (enabled === void 0) { enabled = true; }
749
779
  (_a = this.removeDebugCallback) === null || _a === void 0 ? void 0 : _a.call(this);
780
+ this.debugMode = enabled;
750
781
  if (enabled) {
751
782
  this.removeDebugCallback = this.on('*', function (event, payload) { return console.log('PostHog Debug', event, payload); });
752
783
  }
@@ -777,13 +808,13 @@ var PostHogCoreStateless = /** @class */ (function () {
777
808
  this.enqueue('capture', payload, options);
778
809
  return this;
779
810
  };
780
- PostHogCoreStateless.prototype.aliasStateless = function (alias, distinctId, properties) {
811
+ PostHogCoreStateless.prototype.aliasStateless = function (alias, distinctId, properties, options) {
781
812
  var payload = this.buildPayload({
782
813
  event: '$create_alias',
783
814
  distinct_id: distinctId,
784
815
  properties: __assign(__assign({}, (properties || {})), { distinct_id: distinctId, alias: alias }),
785
816
  });
786
- this.enqueue('alias', payload);
817
+ this.enqueue('alias', payload, options);
787
818
  return this;
788
819
  };
789
820
  /***
@@ -824,7 +855,7 @@ var PostHogCoreStateless = /** @class */ (function () {
824
855
  });
825
856
  });
826
857
  };
827
- PostHogCoreStateless.prototype.getFeatureFlagStateless = function (key, distinctId, groups, personProperties, groupProperties) {
858
+ PostHogCoreStateless.prototype.getFeatureFlagStateless = function (key, distinctId, groups, personProperties, groupProperties, disableGeoip) {
828
859
  if (groups === void 0) { groups = {}; }
829
860
  if (personProperties === void 0) { personProperties = {}; }
830
861
  if (groupProperties === void 0) { groupProperties = {}; }
@@ -832,7 +863,7 @@ var PostHogCoreStateless = /** @class */ (function () {
832
863
  var featureFlags, response;
833
864
  return __generator(this, function (_a) {
834
865
  switch (_a.label) {
835
- case 0: return [4 /*yield*/, this.getFeatureFlagsStateless(distinctId, groups, personProperties, groupProperties)];
866
+ case 0: return [4 /*yield*/, this.getFeatureFlagsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)];
836
867
  case 1:
837
868
  featureFlags = _a.sent();
838
869
  if (!featureFlags) {
@@ -851,7 +882,7 @@ var PostHogCoreStateless = /** @class */ (function () {
851
882
  });
852
883
  });
853
884
  };
854
- PostHogCoreStateless.prototype.getFeatureFlagPayloadStateless = function (key, distinctId, groups, personProperties, groupProperties) {
885
+ PostHogCoreStateless.prototype.getFeatureFlagPayloadStateless = function (key, distinctId, groups, personProperties, groupProperties, disableGeoip) {
855
886
  if (groups === void 0) { groups = {}; }
856
887
  if (personProperties === void 0) { personProperties = {}; }
857
888
  if (groupProperties === void 0) { groupProperties = {}; }
@@ -859,7 +890,7 @@ var PostHogCoreStateless = /** @class */ (function () {
859
890
  var payloads, response;
860
891
  return __generator(this, function (_a) {
861
892
  switch (_a.label) {
862
- case 0: return [4 /*yield*/, this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties)];
893
+ case 0: return [4 /*yield*/, this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)];
863
894
  case 1:
864
895
  payloads = _a.sent();
865
896
  if (!payloads) {
@@ -875,7 +906,7 @@ var PostHogCoreStateless = /** @class */ (function () {
875
906
  });
876
907
  });
877
908
  };
878
- PostHogCoreStateless.prototype.getFeatureFlagPayloadsStateless = function (distinctId, groups, personProperties, groupProperties) {
909
+ PostHogCoreStateless.prototype.getFeatureFlagPayloadsStateless = function (distinctId, groups, personProperties, groupProperties, disableGeoip) {
879
910
  if (groups === void 0) { groups = {}; }
880
911
  if (personProperties === void 0) { personProperties = {}; }
881
912
  if (groupProperties === void 0) { groupProperties = {}; }
@@ -884,7 +915,7 @@ var PostHogCoreStateless = /** @class */ (function () {
884
915
  var _this = this;
885
916
  return __generator(this, function (_a) {
886
917
  switch (_a.label) {
887
- case 0: return [4 /*yield*/, this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties)];
918
+ case 0: return [4 /*yield*/, this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)];
888
919
  case 1:
889
920
  payloads = (_a.sent()).payloads;
890
921
  if (payloads) {
@@ -906,28 +937,33 @@ var PostHogCoreStateless = /** @class */ (function () {
906
937
  return response;
907
938
  }
908
939
  };
909
- PostHogCoreStateless.prototype.getFeatureFlagsStateless = function (distinctId, groups, personProperties, groupProperties) {
940
+ PostHogCoreStateless.prototype.getFeatureFlagsStateless = function (distinctId, groups, personProperties, groupProperties, disableGeoip) {
910
941
  if (groups === void 0) { groups = {}; }
911
942
  if (personProperties === void 0) { personProperties = {}; }
912
943
  if (groupProperties === void 0) { groupProperties = {}; }
913
944
  return __awaiter(this, void 0, void 0, function () {
914
945
  return __generator(this, function (_a) {
915
946
  switch (_a.label) {
916
- case 0: return [4 /*yield*/, this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties)];
947
+ case 0: return [4 /*yield*/, this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)];
917
948
  case 1: return [2 /*return*/, (_a.sent()).flags];
918
949
  }
919
950
  });
920
951
  });
921
952
  };
922
- PostHogCoreStateless.prototype.getFeatureFlagsAndPayloadsStateless = function (distinctId, groups, personProperties, groupProperties) {
953
+ PostHogCoreStateless.prototype.getFeatureFlagsAndPayloadsStateless = function (distinctId, groups, personProperties, groupProperties, disableGeoip) {
923
954
  if (groups === void 0) { groups = {}; }
924
955
  if (personProperties === void 0) { personProperties = {}; }
925
956
  if (groupProperties === void 0) { groupProperties = {}; }
926
957
  return __awaiter(this, void 0, void 0, function () {
927
- var decideResponse, flags, payloads;
958
+ var extraPayload, decideResponse, flags, payloads;
928
959
  return __generator(this, function (_a) {
929
960
  switch (_a.label) {
930
- case 0: return [4 /*yield*/, this.getDecide(distinctId, groups, personProperties, groupProperties)];
961
+ case 0:
962
+ extraPayload = {};
963
+ if (disableGeoip !== null && disableGeoip !== void 0 ? disableGeoip : this.disableGeoip) {
964
+ extraPayload['geoip_disable'] = true;
965
+ }
966
+ return [4 /*yield*/, this.getDecide(distinctId, groups, personProperties, groupProperties, extraPayload)];
931
967
  case 1:
932
968
  decideResponse = _a.sent();
933
969
  flags = decideResponse === null || decideResponse === void 0 ? void 0 : decideResponse.featureFlags;
@@ -945,11 +981,19 @@ var PostHogCoreStateless = /** @class */ (function () {
945
981
  ***/
946
982
  PostHogCoreStateless.prototype.enqueue = function (type, _message, options) {
947
983
  var _this = this;
984
+ var _a;
948
985
  if (this.optedOut) {
949
986
  this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.enable()");
950
987
  return;
951
988
  }
952
989
  var message = __assign(__assign({}, _message), { type: type, library: this.getLibraryId(), library_version: this.getLibraryVersion(), timestamp: (options === null || options === void 0 ? void 0 : options.timestamp) ? options === null || options === void 0 ? void 0 : options.timestamp : currentISOTime() });
990
+ var addGeoipDisableProperty = (_a = options === null || options === void 0 ? void 0 : options.disableGeoip) !== null && _a !== void 0 ? _a : this.disableGeoip;
991
+ if (addGeoipDisableProperty) {
992
+ if (!message.properties) {
993
+ message.properties = {};
994
+ }
995
+ message['properties']['$geoip_disable'] = true;
996
+ }
953
997
  if (message.distinctId) {
954
998
  message.distinct_id = message.distinctId;
955
999
  delete message.distinctId;
@@ -992,8 +1036,14 @@ var PostHogCoreStateless = /** @class */ (function () {
992
1036
  batch: messages,
993
1037
  sent_at: currentISOTime(),
994
1038
  };
1039
+ var promiseUUID = generateUUID();
995
1040
  var done = function (err) {
1041
+ if (err) {
1042
+ _this._events.emit('error', err);
1043
+ }
996
1044
  callback === null || callback === void 0 ? void 0 : callback(err, messages);
1045
+ // remove promise from pendingPromises
1046
+ delete _this.pendingPromises[promiseUUID];
997
1047
  _this._events.emit('flush', messages);
998
1048
  };
999
1049
  // Don't set the user agent if we're not on a browser. The latest spec allows
@@ -1018,13 +1068,11 @@ var PostHogCoreStateless = /** @class */ (function () {
1018
1068
  headers: { 'Content-Type': 'application/json' },
1019
1069
  body: payload,
1020
1070
  };
1021
- this.fetchWithRetry(url, fetchOptions)
1071
+ var requestPromise = this.fetchWithRetry(url, fetchOptions);
1072
+ this.pendingPromises[promiseUUID] = requestPromise;
1073
+ requestPromise
1022
1074
  .then(function () { return done(); })
1023
1075
  .catch(function (err) {
1024
- if (err.response) {
1025
- var error = new Error(err.response.statusText);
1026
- return done(error);
1027
- }
1028
1076
  done(err);
1029
1077
  });
1030
1078
  };
@@ -1034,27 +1082,72 @@ var PostHogCoreStateless = /** @class */ (function () {
1034
1082
  return __awaiter(this, void 0, void 0, function () {
1035
1083
  var _this = this;
1036
1084
  return __generator(this, function (_c) {
1037
- (_a = (_b = AbortSignal).timeout) !== null && _a !== void 0 ? _a : (_b.timeout = function timeout(ms) {
1038
- var ctrl = new AbortController();
1039
- setTimeout(function () { return ctrl.abort(); }, ms);
1040
- return ctrl.signal;
1041
- });
1042
- return [2 /*return*/, retriable(function () {
1043
- return _this.fetch(url, __assign({ signal: AbortSignal.timeout(_this.requestTimeout) }, options));
1044
- }, retryOptions || this._retryOptions)];
1085
+ switch (_c.label) {
1086
+ case 0:
1087
+ (_a = (_b = AbortSignal).timeout) !== null && _a !== void 0 ? _a : (_b.timeout = function timeout(ms) {
1088
+ var ctrl = new AbortController();
1089
+ setTimeout(function () { return ctrl.abort(); }, ms);
1090
+ return ctrl.signal;
1091
+ });
1092
+ return [4 /*yield*/, retriable(function () { return __awaiter(_this, void 0, void 0, function () {
1093
+ var res, e_1;
1094
+ return __generator(this, function (_a) {
1095
+ switch (_a.label) {
1096
+ case 0:
1097
+ res = null;
1098
+ _a.label = 1;
1099
+ case 1:
1100
+ _a.trys.push([1, 3, , 4]);
1101
+ return [4 /*yield*/, this.fetch(url, __assign({ signal: AbortSignal.timeout(this.requestTimeout) }, options))];
1102
+ case 2:
1103
+ res = _a.sent();
1104
+ return [3 /*break*/, 4];
1105
+ case 3:
1106
+ e_1 = _a.sent();
1107
+ // fetch will only throw on network errors or on timeouts
1108
+ throw new PostHogFetchNetworkError(e_1);
1109
+ case 4:
1110
+ if (res.status < 200 || res.status >= 400) {
1111
+ throw new PostHogFetchHttpError(res);
1112
+ }
1113
+ return [2 /*return*/, res];
1114
+ }
1115
+ });
1116
+ }); }, __assign(__assign({}, this._retryOptions), retryOptions))];
1117
+ case 1: return [2 /*return*/, _c.sent()];
1118
+ }
1045
1119
  });
1046
1120
  });
1047
1121
  };
1048
1122
  PostHogCoreStateless.prototype.shutdownAsync = function () {
1049
1123
  return __awaiter(this, void 0, void 0, function () {
1124
+ var e_2;
1050
1125
  return __generator(this, function (_a) {
1051
1126
  switch (_a.label) {
1052
1127
  case 0:
1053
1128
  clearTimeout(this._flushTimer);
1054
- return [4 /*yield*/, this.flushAsync()];
1129
+ _a.label = 1;
1055
1130
  case 1:
1131
+ _a.trys.push([1, 4, , 5]);
1132
+ return [4 /*yield*/, this.flushAsync()];
1133
+ case 2:
1056
1134
  _a.sent();
1057
- return [2 /*return*/];
1135
+ return [4 /*yield*/, Promise.all(Object.values(this.pendingPromises).map(function (x) {
1136
+ return x.catch(function () {
1137
+ // ignore errors as we are shutting down and can't deal with them anyways.
1138
+ });
1139
+ }))];
1140
+ case 3:
1141
+ _a.sent();
1142
+ return [3 /*break*/, 5];
1143
+ case 4:
1144
+ e_2 = _a.sent();
1145
+ if (!isPostHogFetchError(e_2)) {
1146
+ throw e_2;
1147
+ }
1148
+ console.error('Error while shutting down PostHog', e_2);
1149
+ return [3 /*break*/, 5];
1150
+ case 5: return [2 /*return*/];
1058
1151
  }
1059
1152
  });
1060
1153
  });
@@ -1068,17 +1161,13 @@ var PostHogCore = /** @class */ (function (_super) {
1068
1161
  __extends(PostHogCore, _super);
1069
1162
  function PostHogCore(apiKey, options) {
1070
1163
  var _this = this;
1071
- var _a, _b;
1072
- _this = _super.call(this, apiKey, options) || this;
1164
+ var _a, _b, _c;
1165
+ // Default for stateful mode is to not disable geoip. Only override if explicitly set
1166
+ var disableGeoipOption = (_a = options === null || options === void 0 ? void 0 : options.disableGeoip) !== null && _a !== void 0 ? _a : false;
1167
+ _this = _super.call(this, apiKey, __assign(__assign({}, options), { disableGeoip: disableGeoipOption })) || this;
1073
1168
  _this.flagCallReported = {};
1074
- _this.sendFeatureFlagEvent = (_a = options === null || options === void 0 ? void 0 : options.sendFeatureFlagEvent) !== null && _a !== void 0 ? _a : true;
1075
- _this._sessionExpirationTimeSeconds = (_b = options === null || options === void 0 ? void 0 : options.sessionExpirationTimeSeconds) !== null && _b !== void 0 ? _b : 1800; // 30 minutes
1076
- // NOTE: It is important we don't initiate anything in the constructor as some async IO may still be underway on the parent
1077
- if ((options === null || options === void 0 ? void 0 : options.preloadFeatureFlags) !== false) {
1078
- safeSetTimeout(function () {
1079
- _this.reloadFeatureFlags();
1080
- }, 1);
1081
- }
1169
+ _this.sendFeatureFlagEvent = (_b = options === null || options === void 0 ? void 0 : options.sendFeatureFlagEvent) !== null && _b !== void 0 ? _b : true;
1170
+ _this._sessionExpirationTimeSeconds = (_c = options === null || options === void 0 ? void 0 : options.sessionExpirationTimeSeconds) !== null && _c !== void 0 ? _c : 1800; // 30 minutes
1082
1171
  return _this;
1083
1172
  }
1084
1173
  PostHogCore.prototype.setupBootstrap = function (options) {
@@ -1193,9 +1282,7 @@ var PostHogCore = /** @class */ (function (_super) {
1193
1282
  // We keep the AnonymousId to be used by decide calls and identify to link the previousId
1194
1283
  this.setPersistedProperty(PostHogPersistedProperty.AnonymousId, previousDistinctId);
1195
1284
  this.setPersistedProperty(PostHogPersistedProperty.DistinctId, distinctId);
1196
- if (this.getFeatureFlags()) {
1197
- this.reloadFeatureFlags();
1198
- }
1285
+ this.reloadFeatureFlags();
1199
1286
  }
1200
1287
  _super.prototype.identifyStateless.call(this, distinctId, allProperties, options);
1201
1288
  return this;
@@ -1235,7 +1322,7 @@ var PostHogCore = /** @class */ (function (_super) {
1235
1322
  this.register({
1236
1323
  $groups: __assign(__assign({}, existingGroups), groups),
1237
1324
  });
1238
- if (Object.keys(groups).find(function (type) { return existingGroups[type] !== groups[type]; }) && this.getFeatureFlags()) {
1325
+ if (Object.keys(groups).find(function (type) { return existingGroups[type] !== groups[type]; })) {
1239
1326
  this.reloadFeatureFlags();
1240
1327
  }
1241
1328
  return this;
@@ -1468,7 +1555,7 @@ var PostHogCore = /** @class */ (function (_super) {
1468
1555
  return PostHogCore;
1469
1556
  }(PostHogCoreStateless));
1470
1557
 
1471
- var version = "2.2.1";
1558
+ var version = "2.4.0";
1472
1559
 
1473
1560
  function getContext(window) {
1474
1561
  var context = {};
@@ -1833,6 +1920,10 @@ function (_super) {
1833
1920
 
1834
1921
  _this.setupBootstrap(options);
1835
1922
 
1923
+ if ((options === null || options === void 0 ? void 0 : options.preloadFeatureFlags) !== false) {
1924
+ _this.reloadFeatureFlags();
1925
+ }
1926
+
1836
1927
  return _this;
1837
1928
  }
1838
1929