posthog-node 2.0.0-alpha7 → 2.0.1

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/index.cjs.js CHANGED
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var undici = require('undici');
6
+ var crypto = require('crypto');
6
7
 
7
8
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
9
 
@@ -137,12 +138,24 @@ function __generator(thisArg, body) {
137
138
  throw op[1];
138
139
  return { value: op[0] ? op[1] : void 0, done: true };
139
140
  }
141
+ }
142
+ function __spreadArray(to, from, pack) {
143
+ if (pack || arguments.length === 2)
144
+ for (var i = 0, l = from.length, ar; i < l; i++) {
145
+ if (ar || !(i in from)) {
146
+ if (!ar)
147
+ ar = Array.prototype.slice.call(from, 0, i);
148
+ ar[i] = from[i];
149
+ }
150
+ }
151
+ return to.concat(ar || Array.prototype.slice.call(from));
140
152
  }
141
153
 
142
- var version = "2.0.0-alpha7";
154
+ var version = "2.0.1";
143
155
 
144
156
  var PostHogPersistedProperty;
145
157
  (function (PostHogPersistedProperty) {
158
+ PostHogPersistedProperty["AnonymousId"] = "anonymous_id";
146
159
  PostHogPersistedProperty["DistinctId"] = "distinct_id";
147
160
  PostHogPersistedProperty["Props"] = "props";
148
161
  PostHogPersistedProperty["FeatureFlags"] = "feature_flags";
@@ -151,6 +164,8 @@ var PostHogPersistedProperty;
151
164
  PostHogPersistedProperty["OptedOut"] = "opted_out";
152
165
  PostHogPersistedProperty["SessionId"] = "session_id";
153
166
  PostHogPersistedProperty["SessionLastTimestamp"] = "session_timestamp";
167
+ PostHogPersistedProperty["PersonProperties"] = "person_properties";
168
+ PostHogPersistedProperty["GroupProperties"] = "group_properties";
154
169
  })(PostHogPersistedProperty || (PostHogPersistedProperty = {}));
155
170
 
156
171
  function assert(truthyValue, message) {
@@ -697,7 +712,7 @@ var SimpleEventEmitter = /** @class */ (function () {
697
712
  var PostHogCore = /** @class */ (function () {
698
713
  function PostHogCore(apiKey, options) {
699
714
  var _this = this;
700
- var _a, _b, _c, _d, _e, _f;
715
+ var _a, _b, _c, _d, _e;
701
716
  this.flagCallReported = {};
702
717
  // internal
703
718
  this._events = new SimpleEventEmitter();
@@ -708,14 +723,13 @@ var PostHogCore = /** @class */ (function () {
708
723
  this.flushInterval = (_a = options === null || options === void 0 ? void 0 : options.flushInterval) !== null && _a !== void 0 ? _a : 10000;
709
724
  this.captureMode = (options === null || options === void 0 ? void 0 : options.captureMode) || 'form';
710
725
  this.sendFeatureFlagEvent = (_b = options === null || options === void 0 ? void 0 : options.sendFeatureFlagEvent) !== null && _b !== void 0 ? _b : true;
711
- this._decidePollInterval = Math.max(0, (_c = options === null || options === void 0 ? void 0 : options.decidePollInterval) !== null && _c !== void 0 ? _c : 30000);
712
726
  // If enable is explicitly set to false we override the optout
713
727
  this._optoutOverride = (options === null || options === void 0 ? void 0 : options.enable) === false;
714
728
  this._retryOptions = {
715
- retryCount: (_d = options === null || options === void 0 ? void 0 : options.fetchRetryCount) !== null && _d !== void 0 ? _d : 3,
716
- retryDelay: (_e = options === null || options === void 0 ? void 0 : options.fetchRetryDelay) !== null && _e !== void 0 ? _e : 3000,
729
+ retryCount: (_c = options === null || options === void 0 ? void 0 : options.fetchRetryCount) !== null && _c !== void 0 ? _c : 3,
730
+ retryDelay: (_d = options === null || options === void 0 ? void 0 : options.fetchRetryDelay) !== null && _d !== void 0 ? _d : 3000,
717
731
  };
718
- this._sessionExpirationTimeSeconds = (_f = options === null || options === void 0 ? void 0 : options.sessionExpirationTimeSeconds) !== null && _f !== void 0 ? _f : 1800; // 30 minutes
732
+ this._sessionExpirationTimeSeconds = (_e = options === null || options === void 0 ? void 0 : options.sessionExpirationTimeSeconds) !== null && _e !== void 0 ? _e : 1800; // 30 minutes
719
733
  // NOTE: It is important we don't initiate anything in the constructor as some async IO may still be underway on the parent
720
734
  if ((options === null || options === void 0 ? void 0 : options.preloadFeatureFlags) !== false) {
721
735
  safeSetTimeout(function () {
@@ -725,12 +739,14 @@ var PostHogCore = /** @class */ (function () {
725
739
  }
726
740
  PostHogCore.prototype.getCommonEventProperties = function () {
727
741
  var featureFlags = this.getFeatureFlags();
728
- return {
729
- $lib: this.getLibraryId(),
730
- $lib_version: this.getLibraryVersion(),
731
- $active_feature_flags: featureFlags ? Object.keys(featureFlags) : undefined,
732
- $enabled_feature_flags: featureFlags,
733
- };
742
+ var featureVariantProperties = {};
743
+ if (featureFlags) {
744
+ for (var _i = 0, _a = Object.entries(featureFlags); _i < _a.length; _i++) {
745
+ var _b = _a[_i], feature = _b[0], variant = _b[1];
746
+ featureVariantProperties["$feature/".concat(feature)] = variant;
747
+ }
748
+ }
749
+ return __assign({ $lib: this.getLibraryId(), $lib_version: this.getLibraryVersion(), $active_feature_flags: featureFlags ? Object.keys(featureFlags) : undefined }, featureVariantProperties);
734
750
  };
735
751
  Object.defineProperty(PostHogCore.prototype, "props", {
736
752
  // NOTE: Props are lazy loaded from localstorage hence the complex getter setter logic
@@ -746,6 +762,9 @@ var PostHogCore = /** @class */ (function () {
746
762
  enumerable: false,
747
763
  configurable: true
748
764
  });
765
+ PostHogCore.prototype.clearProps = function () {
766
+ this.props = undefined;
767
+ };
749
768
  Object.defineProperty(PostHogCore.prototype, "optedOut", {
750
769
  get: function () {
751
770
  var _a, _b;
@@ -763,11 +782,16 @@ var PostHogCore = /** @class */ (function () {
763
782
  PostHogCore.prototype.on = function (event, cb) {
764
783
  return this._events.on(event, cb);
765
784
  };
766
- PostHogCore.prototype.reset = function () {
767
- for (var key in PostHogPersistedProperty) {
768
- this.setPersistedProperty(PostHogPersistedProperty[key], null);
785
+ PostHogCore.prototype.reset = function (propertiesToKeep) {
786
+ var allPropertiesToKeep = __spreadArray([PostHogPersistedProperty.Queue], (propertiesToKeep || []), true);
787
+ // clean up props
788
+ this.clearProps();
789
+ for (var _i = 0, _a = Object.keys(PostHogPersistedProperty); _i < _a.length; _i++) {
790
+ var key = _a[_i];
791
+ if (!allPropertiesToKeep.includes(PostHogPersistedProperty[key])) {
792
+ this.setPersistedProperty(PostHogPersistedProperty[key], null);
793
+ }
769
794
  }
770
- this.setPersistedProperty(PostHogPersistedProperty.DistinctId, generateUUID(globalThis));
771
795
  };
772
796
  PostHogCore.prototype.debug = function (enabled) {
773
797
  var _a;
@@ -797,13 +821,16 @@ var PostHogCore = /** @class */ (function () {
797
821
  PostHogCore.prototype.resetSessionId = function () {
798
822
  this.setPersistedProperty(PostHogPersistedProperty.SessionId, null);
799
823
  };
800
- PostHogCore.prototype.getDistinctId = function () {
801
- var distinctId = this.getPersistedProperty(PostHogPersistedProperty.DistinctId);
802
- if (!distinctId) {
803
- distinctId = generateUUID(globalThis);
804
- this.setPersistedProperty(PostHogPersistedProperty.DistinctId, distinctId);
824
+ PostHogCore.prototype.getAnonymousId = function () {
825
+ var anonId = this.getPersistedProperty(PostHogPersistedProperty.AnonymousId);
826
+ if (!anonId) {
827
+ anonId = generateUUID(globalThis);
828
+ this.setPersistedProperty(PostHogPersistedProperty.AnonymousId, anonId);
805
829
  }
806
- return distinctId;
830
+ return anonId;
831
+ };
832
+ PostHogCore.prototype.getDistinctId = function () {
833
+ return this.getPersistedProperty(PostHogPersistedProperty.DistinctId) || this.getAnonymousId();
807
834
  };
808
835
  PostHogCore.prototype.register = function (properties) {
809
836
  this.props = __assign(__assign({}, this.props), properties);
@@ -817,32 +844,39 @@ var PostHogCore = /** @class */ (function () {
817
844
  *** TRACKING
818
845
  ***/
819
846
  PostHogCore.prototype.identify = function (distinctId, properties) {
820
- distinctId = distinctId || this.getDistinctId();
847
+ var previousDistinctId = this.getDistinctId();
848
+ distinctId = distinctId || previousDistinctId;
821
849
  if (properties === null || properties === void 0 ? void 0 : properties.$groups) {
822
850
  this.groups(properties.$groups);
823
851
  }
824
852
  var payload = __assign(__assign({}, this.buildPayload({
825
853
  distinct_id: distinctId,
826
854
  event: '$identify',
827
- properties: __assign(__assign({}, (properties || {})), { $anon_distinct_id: this.getDistinctId() }),
855
+ properties: __assign(__assign({}, (properties || {})), { $anon_distinct_id: this.getAnonymousId() }),
828
856
  })), { $set: properties });
829
- if (distinctId !== this.getDistinctId()) {
857
+ if (distinctId !== previousDistinctId) {
858
+ // We keep the AnonymousId to be used by decide calls and identify to link the previousId
859
+ this.setPersistedProperty(PostHogPersistedProperty.AnonymousId, previousDistinctId);
830
860
  this.setPersistedProperty(PostHogPersistedProperty.DistinctId, distinctId);
861
+ if (this.getFeatureFlags()) {
862
+ void this.reloadFeatureFlagsAsync();
863
+ }
831
864
  }
832
865
  this.enqueue('identify', payload);
833
866
  return this;
834
867
  };
835
- PostHogCore.prototype.capture = function (event, properties) {
836
- // NOTE: Legacy nodejs implementation uses groups
837
- if (properties && properties['groups']) {
838
- properties.$groups = properties.groups;
839
- delete properties.groups;
840
- }
868
+ PostHogCore.prototype.capture = function (event, properties, forceSendFeatureFlags) {
869
+ if (forceSendFeatureFlags === void 0) { forceSendFeatureFlags = false; }
841
870
  if (properties === null || properties === void 0 ? void 0 : properties.$groups) {
842
871
  this.groups(properties.$groups);
843
872
  }
844
- var payload = this.buildPayload({ event: event, properties: properties });
845
- this.enqueue('capture', payload);
873
+ if (forceSendFeatureFlags) {
874
+ this._sendFeatureFlags(event, properties);
875
+ }
876
+ else {
877
+ var payload = this.buildPayload({ event: event, properties: properties });
878
+ this.enqueue('capture', payload);
879
+ }
846
880
  return this;
847
881
  };
848
882
  PostHogCore.prototype.alias = function (alias) {
@@ -872,11 +906,10 @@ var PostHogCore = /** @class */ (function () {
872
906
  PostHogCore.prototype.groups = function (groups) {
873
907
  // Get persisted groups
874
908
  var existingGroups = this.props.$groups || {};
875
- // NOTE: Should we do the same for groups listed in identify / capture?
876
909
  this.register({
877
910
  $groups: __assign(__assign({}, existingGroups), groups),
878
911
  });
879
- if (Object.keys(groups).find(function (type) { return existingGroups[type] !== groups[type]; }) && this._decideResponsePromise) {
912
+ if (Object.keys(groups).find(function (type) { return existingGroups[type] !== groups[type]; }) && this.getFeatureFlags()) {
880
913
  void this.reloadFeatureFlagsAsync();
881
914
  }
882
915
  return this;
@@ -900,58 +933,96 @@ var PostHogCore = /** @class */ (function () {
900
933
  this.enqueue('capture', payload);
901
934
  return this;
902
935
  };
936
+ /***
937
+ * PROPERTIES
938
+ ***/
939
+ PostHogCore.prototype.personProperties = function (properties) {
940
+ // Get persisted person properties
941
+ var existingProperties = this.getPersistedProperty(PostHogPersistedProperty.PersonProperties) || {};
942
+ this.setPersistedProperty(PostHogPersistedProperty.PersonProperties, __assign(__assign({}, existingProperties), properties));
943
+ return this;
944
+ };
945
+ PostHogCore.prototype.groupProperties = function (properties) {
946
+ // Get persisted group properties
947
+ var existingProperties = this.getPersistedProperty(PostHogPersistedProperty.GroupProperties) || {};
948
+ if (Object.keys(existingProperties).length !== 0) {
949
+ Object.keys(existingProperties).forEach(function (groupType) {
950
+ existingProperties[groupType] = __assign(__assign({}, existingProperties[groupType]), properties[groupType]);
951
+ delete properties[groupType];
952
+ });
953
+ }
954
+ this.setPersistedProperty(PostHogPersistedProperty.GroupProperties, __assign(__assign({}, existingProperties), properties));
955
+ return this;
956
+ };
903
957
  /***
904
958
  *** FEATURE FLAGS
905
959
  ***/
906
- PostHogCore.prototype.decideAsync = function () {
960
+ PostHogCore.prototype.decideAsync = function (sendAnonDistinctId) {
961
+ if (sendAnonDistinctId === void 0) { sendAnonDistinctId = true; }
907
962
  if (this._decideResponsePromise) {
908
963
  return this._decideResponsePromise;
909
964
  }
910
- return this._decideAsync();
965
+ return this._decideAsync(sendAnonDistinctId);
911
966
  };
912
- PostHogCore.prototype._decideAsync = function () {
967
+ PostHogCore.prototype._decideAsync = function (sendAnonDistinctId) {
968
+ if (sendAnonDistinctId === void 0) { sendAnonDistinctId = true; }
913
969
  return __awaiter(this, void 0, void 0, function () {
914
- var url, distinctId, groups, fetchOptions;
970
+ var url, distinctId, groups, personProperties, groupProperties, fetchOptions;
915
971
  var _this = this;
916
972
  return __generator(this, function (_a) {
917
973
  url = "".concat(this.host, "/decide/?v=2");
918
974
  distinctId = this.getDistinctId();
919
975
  groups = this.props.$groups || {};
976
+ personProperties = this.getPersistedProperty(PostHogPersistedProperty.PersonProperties) || {};
977
+ groupProperties = this.getPersistedProperty(PostHogPersistedProperty.GroupProperties) || {};
920
978
  fetchOptions = {
921
979
  method: 'POST',
922
980
  headers: { 'Content-Type': 'application/json' },
923
- body: JSON.stringify({ groups: groups, distinct_id: distinctId, token: this.apiKey }),
981
+ body: JSON.stringify({
982
+ token: this.apiKey,
983
+ distinct_id: distinctId,
984
+ $anon_distinct_id: sendAnonDistinctId ? this.getAnonymousId() : undefined,
985
+ groups: groups,
986
+ person_properties: personProperties,
987
+ group_properties: groupProperties,
988
+ }),
924
989
  };
925
990
  this._decideResponsePromise = this.fetchWithRetry(url, fetchOptions)
926
991
  .then(function (r) { return r.json(); })
927
992
  .then(function (res) {
928
993
  if (res.featureFlags) {
929
994
  _this.setPersistedProperty(PostHogPersistedProperty.FeatureFlags, res.featureFlags);
995
+ _this._events.emit('featureflags', res.featureFlags);
930
996
  }
931
- _this._events.emit('featureflags', res.featureFlags);
932
997
  return res;
998
+ })
999
+ .finally(function () {
1000
+ _this._decideResponsePromise = undefined;
933
1001
  });
934
1002
  return [2 /*return*/, this._decideResponsePromise];
935
1003
  });
936
1004
  });
937
1005
  };
938
- PostHogCore.prototype.getFeatureFlag = function (key, defaultResult) {
939
- var _a;
940
- if (defaultResult === void 0) { defaultResult = false; }
1006
+ PostHogCore.prototype.getFeatureFlag = function (key) {
941
1007
  var featureFlags = this.getFeatureFlags();
942
1008
  if (!featureFlags) {
943
- // If we haven't loaded flags yet we respond undefined to indicate this
1009
+ // If we haven't loaded flags yet, or errored out, we respond with undefined
944
1010
  return undefined;
945
1011
  }
1012
+ var response = featureFlags[key];
1013
+ if (response === undefined) {
1014
+ // `/decide` returns nothing for flags which are false.
1015
+ response = false;
1016
+ }
946
1017
  if (this.sendFeatureFlagEvent && !this.flagCallReported[key]) {
947
1018
  this.flagCallReported[key] = true;
948
1019
  this.capture('$feature_flag_called', {
949
1020
  $feature_flag: key,
950
- $feature_flag_response: featureFlags[key],
1021
+ $feature_flag_response: response,
951
1022
  });
952
1023
  }
953
- // If we have flags we either return the value (true or string) or the defaultResult
954
- return (_a = featureFlags[key]) !== null && _a !== void 0 ? _a : defaultResult;
1024
+ // If we have flags we either return the value (true or string) or false
1025
+ return response;
955
1026
  };
956
1027
  PostHogCore.prototype.getFeatureFlags = function () {
957
1028
  var flags = this.getPersistedProperty(PostHogPersistedProperty.FeatureFlags);
@@ -970,35 +1041,26 @@ var PostHogCore = /** @class */ (function () {
970
1041
  }
971
1042
  return flags;
972
1043
  };
973
- PostHogCore.prototype.isFeatureEnabled = function (key, defaultResult) {
974
- var _a;
975
- if (defaultResult === void 0) { defaultResult = false; }
976
- var flag = (_a = this.getFeatureFlag(key, defaultResult)) !== null && _a !== void 0 ? _a : defaultResult;
977
- return !!flag;
1044
+ PostHogCore.prototype.isFeatureEnabled = function (key) {
1045
+ var response = this.getFeatureFlag(key);
1046
+ if (response === undefined) {
1047
+ return undefined;
1048
+ }
1049
+ return !!response;
978
1050
  };
979
- PostHogCore.prototype.reloadFeatureFlagsAsync = function () {
1051
+ PostHogCore.prototype.reloadFeatureFlagsAsync = function (sendAnonDistinctId) {
1052
+ if (sendAnonDistinctId === void 0) { sendAnonDistinctId = true; }
980
1053
  return __awaiter(this, void 0, void 0, function () {
981
- var _this = this;
982
1054
  return __generator(this, function (_a) {
983
1055
  switch (_a.label) {
984
- case 0:
985
- clearTimeout(this._decideTimer);
986
- if (this._decidePollInterval) {
987
- this._decideTimer = safeSetTimeout(function () { return _this.reloadFeatureFlagsAsync(); }, this._decidePollInterval);
988
- }
989
- this._decideResponsePromise = undefined;
990
- return [4 /*yield*/, this.decideAsync()];
1056
+ case 0: return [4 /*yield*/, this.decideAsync(sendAnonDistinctId)];
991
1057
  case 1: return [2 /*return*/, (_a.sent()).featureFlags];
992
1058
  }
993
1059
  });
994
1060
  });
995
1061
  };
996
- // When listening to feature flags polling is active
997
1062
  PostHogCore.prototype.onFeatureFlags = function (cb) {
998
1063
  var _this = this;
999
- if (!this._decideTimer) {
1000
- void this.reloadFeatureFlagsAsync();
1001
- }
1002
1064
  return this.on('featureflags', function () { return __awaiter(_this, void 0, void 0, function () {
1003
1065
  var flags;
1004
1066
  return __generator(this, function (_a) {
@@ -1010,12 +1072,33 @@ var PostHogCore = /** @class */ (function () {
1010
1072
  });
1011
1073
  }); });
1012
1074
  };
1075
+ PostHogCore.prototype.onFeatureFlag = function (key, cb) {
1076
+ var _this = this;
1077
+ return this.on('featureflags', function () { return __awaiter(_this, void 0, void 0, function () {
1078
+ var flagResponse;
1079
+ return __generator(this, function (_a) {
1080
+ flagResponse = this.getFeatureFlag(key);
1081
+ if (flagResponse !== undefined) {
1082
+ cb(flagResponse);
1083
+ }
1084
+ return [2 /*return*/];
1085
+ });
1086
+ }); });
1087
+ };
1013
1088
  PostHogCore.prototype.overrideFeatureFlag = function (flags) {
1014
1089
  if (flags === null) {
1015
1090
  return this.setPersistedProperty(PostHogPersistedProperty.OverrideFeatureFlags, null);
1016
1091
  }
1017
1092
  return this.setPersistedProperty(PostHogPersistedProperty.OverrideFeatureFlags, flags);
1018
1093
  };
1094
+ PostHogCore.prototype._sendFeatureFlags = function (event, properties) {
1095
+ var _this = this;
1096
+ this.reloadFeatureFlagsAsync(false).finally(function () {
1097
+ // Try to enqueue message irrespective of errors during feature flag fetching
1098
+ var payload = _this.buildPayload({ event: event, properties: properties });
1099
+ _this.enqueue('capture', payload);
1100
+ });
1101
+ };
1019
1102
  /***
1020
1103
  *** QUEUEING AND FLUSHING
1021
1104
  ***/
@@ -1044,13 +1127,15 @@ var PostHogCore = /** @class */ (function () {
1044
1127
  PostHogCore.prototype.flushAsync = function () {
1045
1128
  var _this = this;
1046
1129
  return new Promise(function (resolve, reject) {
1047
- _this.flush(function (err, data) { return (err ? reject(err) : resolve(data)); });
1130
+ _this.flush(function (err, data) {
1131
+ return err ? reject(err) : resolve(data);
1132
+ });
1048
1133
  });
1049
1134
  };
1050
1135
  PostHogCore.prototype.flush = function (callback) {
1051
1136
  var _this = this;
1052
1137
  if (this.optedOut) {
1053
- return callback && safeSetTimeout(callback, 0);
1138
+ return callback === null || callback === void 0 ? void 0 : callback();
1054
1139
  }
1055
1140
  if (this._flushTimer) {
1056
1141
  clearTimeout(this._flushTimer);
@@ -1058,7 +1143,7 @@ var PostHogCore = /** @class */ (function () {
1058
1143
  }
1059
1144
  var queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
1060
1145
  if (!queue.length) {
1061
- return callback && safeSetTimeout(callback, 0);
1146
+ return callback === null || callback === void 0 ? void 0 : callback();
1062
1147
  }
1063
1148
  var items = queue.splice(0, this.flushAt);
1064
1149
  this.setPersistedProperty(PostHogPersistedProperty.Queue, queue);
@@ -1117,7 +1202,6 @@ var PostHogCore = /** @class */ (function () {
1117
1202
  return __generator(this, function (_a) {
1118
1203
  switch (_a.label) {
1119
1204
  case 0:
1120
- clearTimeout(this._decideTimer);
1121
1205
  clearTimeout(this._flushTimer);
1122
1206
  return [4 /*yield*/, this.flushAsync()];
1123
1207
  case 1:
@@ -1146,6 +1230,553 @@ var PostHogMemoryStorage = /** @class */ (function () {
1146
1230
  return PostHogMemoryStorage;
1147
1231
  }());
1148
1232
 
1233
+ var LONG_SCALE = 0xfffffffffffffff;
1234
+
1235
+ var ClientError =
1236
+ /** @class */
1237
+ function (_super) {
1238
+ __extends(ClientError, _super);
1239
+
1240
+ function ClientError(message) {
1241
+ var _this = _super.call(this) || this;
1242
+
1243
+ Error.captureStackTrace(_this, _this.constructor);
1244
+ _this.name = 'ClientError';
1245
+ _this.message = message;
1246
+ Object.setPrototypeOf(_this, ClientError.prototype);
1247
+ return _this;
1248
+ }
1249
+
1250
+ return ClientError;
1251
+ }(Error);
1252
+
1253
+ var InconclusiveMatchError =
1254
+ /** @class */
1255
+ function (_super) {
1256
+ __extends(InconclusiveMatchError, _super);
1257
+
1258
+ function InconclusiveMatchError(message) {
1259
+ var _this = _super.call(this, message) || this;
1260
+
1261
+ _this.name = _this.constructor.name;
1262
+ Error.captureStackTrace(_this, _this.constructor); // instanceof doesn't work in ES3 or ES5
1263
+ // https://www.dannyguo.com/blog/how-to-fix-instanceof-not-working-for-custom-errors-in-typescript/
1264
+ // this is the workaround
1265
+
1266
+ Object.setPrototypeOf(_this, InconclusiveMatchError.prototype);
1267
+ return _this;
1268
+ }
1269
+
1270
+ return InconclusiveMatchError;
1271
+ }(Error);
1272
+
1273
+ var FeatureFlagsPoller =
1274
+ /** @class */
1275
+ function () {
1276
+ function FeatureFlagsPoller(_a) {
1277
+ var pollingInterval = _a.pollingInterval,
1278
+ personalApiKey = _a.personalApiKey,
1279
+ projectApiKey = _a.projectApiKey,
1280
+ timeout = _a.timeout,
1281
+ host = _a.host;
1282
+ this.pollingInterval = pollingInterval;
1283
+ this.personalApiKey = personalApiKey;
1284
+ this.featureFlags = [];
1285
+ this.groupTypeMapping = {};
1286
+ this.loadedSuccessfullyOnce = false;
1287
+ this.timeout = timeout;
1288
+ this.projectApiKey = projectApiKey;
1289
+ this.host = host;
1290
+ this.poller = undefined;
1291
+ void this.loadFeatureFlags();
1292
+ }
1293
+
1294
+ FeatureFlagsPoller.prototype.getFeatureFlag = function (key, distinctId, groups, personProperties, groupProperties) {
1295
+ if (groups === void 0) {
1296
+ groups = {};
1297
+ }
1298
+
1299
+ if (personProperties === void 0) {
1300
+ personProperties = {};
1301
+ }
1302
+
1303
+ if (groupProperties === void 0) {
1304
+ groupProperties = {};
1305
+ }
1306
+
1307
+ return __awaiter(this, void 0, void 0, function () {
1308
+ var response, featureFlag, _i, _a, flag;
1309
+
1310
+ return __generator(this, function (_b) {
1311
+ switch (_b.label) {
1312
+ case 0:
1313
+ return [4
1314
+ /*yield*/
1315
+ , this.loadFeatureFlags()];
1316
+
1317
+ case 1:
1318
+ _b.sent();
1319
+
1320
+ response = undefined;
1321
+ featureFlag = undefined;
1322
+
1323
+ if (!this.loadedSuccessfullyOnce) {
1324
+ return [2
1325
+ /*return*/
1326
+ , response];
1327
+ }
1328
+
1329
+ for (_i = 0, _a = this.featureFlags; _i < _a.length; _i++) {
1330
+ flag = _a[_i];
1331
+
1332
+ if (key === flag.key) {
1333
+ featureFlag = flag;
1334
+ break;
1335
+ }
1336
+ }
1337
+
1338
+ if (featureFlag !== undefined) {
1339
+ try {
1340
+ response = this.computeFlagLocally(featureFlag, distinctId, groups, personProperties, groupProperties);
1341
+ console.debug("Successfully computed flag locally: ".concat(key, " -> ").concat(response));
1342
+ } catch (e) {
1343
+ if (e instanceof InconclusiveMatchError) {
1344
+ console.debug("Can't compute flag locally: ".concat(key, ": ").concat(e));
1345
+ } else if (e instanceof Error) {
1346
+ console.error("Error computing flag locally: ".concat(key, ": ").concat(e));
1347
+ }
1348
+ }
1349
+ }
1350
+
1351
+ return [2
1352
+ /*return*/
1353
+ , response];
1354
+ }
1355
+ });
1356
+ });
1357
+ };
1358
+
1359
+ FeatureFlagsPoller.prototype.getAllFlags = function (distinctId, groups, personProperties, groupProperties) {
1360
+ if (groups === void 0) {
1361
+ groups = {};
1362
+ }
1363
+
1364
+ if (personProperties === void 0) {
1365
+ personProperties = {};
1366
+ }
1367
+
1368
+ if (groupProperties === void 0) {
1369
+ groupProperties = {};
1370
+ }
1371
+
1372
+ return __awaiter(this, void 0, void 0, function () {
1373
+ var response, fallbackToDecide;
1374
+
1375
+ var _this = this;
1376
+
1377
+ return __generator(this, function (_a) {
1378
+ switch (_a.label) {
1379
+ case 0:
1380
+ return [4
1381
+ /*yield*/
1382
+ , this.loadFeatureFlags()];
1383
+
1384
+ case 1:
1385
+ _a.sent();
1386
+
1387
+ response = {};
1388
+ fallbackToDecide = this.featureFlags.length == 0;
1389
+ this.featureFlags.map(function (flag) {
1390
+ try {
1391
+ response[flag.key] = _this.computeFlagLocally(flag, distinctId, groups, personProperties, groupProperties);
1392
+ } catch (e) {
1393
+ if (e instanceof InconclusiveMatchError) ; else if (e instanceof Error) {
1394
+ console.error("Error computing flag locally: ".concat(flag.key, ": ").concat(e));
1395
+ }
1396
+
1397
+ fallbackToDecide = true;
1398
+ }
1399
+ });
1400
+ return [2
1401
+ /*return*/
1402
+ , {
1403
+ response: response,
1404
+ fallbackToDecide: fallbackToDecide
1405
+ }];
1406
+ }
1407
+ });
1408
+ });
1409
+ };
1410
+
1411
+ FeatureFlagsPoller.prototype.computeFlagLocally = function (flag, distinctId, groups, personProperties, groupProperties) {
1412
+ if (groups === void 0) {
1413
+ groups = {};
1414
+ }
1415
+
1416
+ if (personProperties === void 0) {
1417
+ personProperties = {};
1418
+ }
1419
+
1420
+ if (groupProperties === void 0) {
1421
+ groupProperties = {};
1422
+ }
1423
+
1424
+ if (flag.ensure_experience_continuity) {
1425
+ throw new InconclusiveMatchError('Flag has experience continuity enabled');
1426
+ }
1427
+
1428
+ if (!flag.active) {
1429
+ return false;
1430
+ }
1431
+
1432
+ var flagFilters = flag.filters || {};
1433
+ var aggregation_group_type_index = flagFilters.aggregation_group_type_index;
1434
+
1435
+ if (aggregation_group_type_index != undefined) {
1436
+ var groupName = this.groupTypeMapping[String(aggregation_group_type_index)];
1437
+
1438
+ if (!groupName) {
1439
+ console.warn("[FEATURE FLAGS] Unknown group type index ".concat(aggregation_group_type_index, " for feature flag ").concat(flag.key));
1440
+ throw new InconclusiveMatchError('Flag has unknown group type index');
1441
+ }
1442
+
1443
+ if (!(groupName in groups)) {
1444
+ console.warn("[FEATURE FLAGS] Can't compute group feature flag: ".concat(flag.key, " without group names passed in"));
1445
+ return false;
1446
+ }
1447
+
1448
+ var focusedGroupProperties = groupProperties[groupName];
1449
+ return this.matchFeatureFlagProperties(flag, groups[groupName], focusedGroupProperties);
1450
+ } else {
1451
+ return this.matchFeatureFlagProperties(flag, distinctId, personProperties);
1452
+ }
1453
+ };
1454
+
1455
+ FeatureFlagsPoller.prototype.matchFeatureFlagProperties = function (flag, distinctId, properties) {
1456
+ var _this = this;
1457
+
1458
+ var flagFilters = flag.filters || {};
1459
+ var flagConditions = flagFilters.groups || [];
1460
+ var isInconclusive = false;
1461
+ var result = undefined;
1462
+ flagConditions.forEach(function (condition) {
1463
+ try {
1464
+ if (_this.isConditionMatch(flag, distinctId, condition, properties)) {
1465
+ result = _this.getMatchingVariant(flag, distinctId) || true;
1466
+ }
1467
+ } catch (e) {
1468
+ if (e instanceof InconclusiveMatchError) {
1469
+ isInconclusive = true;
1470
+ } else {
1471
+ throw e;
1472
+ }
1473
+ }
1474
+ });
1475
+
1476
+ if (result !== undefined) {
1477
+ return result;
1478
+ } else if (isInconclusive) {
1479
+ throw new InconclusiveMatchError("Can't determine if feature flag is enabled or not with given properties");
1480
+ } // We can only return False when all conditions are False
1481
+
1482
+
1483
+ return false;
1484
+ };
1485
+
1486
+ FeatureFlagsPoller.prototype.isConditionMatch = function (flag, distinctId, condition, properties) {
1487
+ var rolloutPercentage = condition.rollout_percentage;
1488
+
1489
+ if ((condition.properties || []).length > 0) {
1490
+ var matchAll = condition.properties.every(function (property) {
1491
+ return matchProperty(property, properties);
1492
+ });
1493
+
1494
+ if (!matchAll) {
1495
+ return false;
1496
+ } else if (rolloutPercentage == undefined) {
1497
+ // == to include `null` as a match, not just `undefined`
1498
+ return true;
1499
+ }
1500
+ }
1501
+
1502
+ if (rolloutPercentage != undefined && _hash(flag.key, distinctId) > rolloutPercentage / 100.0) {
1503
+ return false;
1504
+ }
1505
+
1506
+ return true;
1507
+ };
1508
+
1509
+ FeatureFlagsPoller.prototype.getMatchingVariant = function (flag, distinctId) {
1510
+ var hashValue = _hash(flag.key, distinctId, 'variant');
1511
+
1512
+ var matchingVariant = this.variantLookupTable(flag).find(function (variant) {
1513
+ return hashValue >= variant.valueMin && hashValue < variant.valueMax;
1514
+ });
1515
+
1516
+ if (matchingVariant) {
1517
+ return matchingVariant.key;
1518
+ }
1519
+
1520
+ return undefined;
1521
+ };
1522
+
1523
+ FeatureFlagsPoller.prototype.variantLookupTable = function (flag) {
1524
+ var _a;
1525
+
1526
+ var lookupTable = [];
1527
+ var valueMin = 0;
1528
+ var valueMax = 0;
1529
+ var flagFilters = flag.filters || {};
1530
+ var multivariates = ((_a = flagFilters.multivariate) === null || _a === void 0 ? void 0 : _a.variants) || [];
1531
+ multivariates.forEach(function (variant) {
1532
+ valueMax = valueMin + variant.rollout_percentage / 100.0;
1533
+ lookupTable.push({
1534
+ valueMin: valueMin,
1535
+ valueMax: valueMax,
1536
+ key: variant.key
1537
+ });
1538
+ valueMin = valueMax;
1539
+ });
1540
+ return lookupTable;
1541
+ };
1542
+
1543
+ FeatureFlagsPoller.prototype.loadFeatureFlags = function (forceReload) {
1544
+ if (forceReload === void 0) {
1545
+ forceReload = false;
1546
+ }
1547
+
1548
+ return __awaiter(this, void 0, void 0, function () {
1549
+ return __generator(this, function (_a) {
1550
+ switch (_a.label) {
1551
+ case 0:
1552
+ if (!(!this.loadedSuccessfullyOnce || forceReload)) return [3
1553
+ /*break*/
1554
+ , 2];
1555
+ return [4
1556
+ /*yield*/
1557
+ , this._loadFeatureFlags()];
1558
+
1559
+ case 1:
1560
+ _a.sent();
1561
+
1562
+ _a.label = 2;
1563
+
1564
+ case 2:
1565
+ return [2
1566
+ /*return*/
1567
+ ];
1568
+ }
1569
+ });
1570
+ });
1571
+ };
1572
+
1573
+ FeatureFlagsPoller.prototype._loadFeatureFlags = function () {
1574
+ return __awaiter(this, void 0, void 0, function () {
1575
+ var res, responseJson, err_1;
1576
+
1577
+ var _this = this;
1578
+
1579
+ return __generator(this, function (_a) {
1580
+ switch (_a.label) {
1581
+ case 0:
1582
+ if (this.poller) {
1583
+ clearTimeout(this.poller);
1584
+ this.poller = undefined;
1585
+ }
1586
+
1587
+ this.poller = setTimeout(function () {
1588
+ return _this._loadFeatureFlags();
1589
+ }, this.pollingInterval);
1590
+ _a.label = 1;
1591
+
1592
+ case 1:
1593
+ _a.trys.push([1, 4,, 5]);
1594
+
1595
+ return [4
1596
+ /*yield*/
1597
+ , this._requestFeatureFlagDefinitions()];
1598
+
1599
+ case 2:
1600
+ res = _a.sent();
1601
+
1602
+ if (res && res.statusCode === 401) {
1603
+ throw new ClientError("Your personalApiKey is invalid. Are you sure you're not using your Project API key? More information: https://posthog.com/docs/api/overview");
1604
+ }
1605
+
1606
+ return [4
1607
+ /*yield*/
1608
+ , res.body.json()];
1609
+
1610
+ case 3:
1611
+ responseJson = _a.sent();
1612
+
1613
+ if (!('flags' in responseJson)) {
1614
+ console.error("Invalid response when getting feature flags: ".concat(JSON.stringify(responseJson)));
1615
+ }
1616
+
1617
+ this.featureFlags = responseJson.flags || [];
1618
+ this.groupTypeMapping = responseJson.group_type_mapping || {};
1619
+ this.loadedSuccessfullyOnce = true;
1620
+ return [3
1621
+ /*break*/
1622
+ , 5];
1623
+
1624
+ case 4:
1625
+ err_1 = _a.sent(); // if an error that is not an instance of ClientError is thrown
1626
+ // we silently ignore the error when reloading feature flags
1627
+
1628
+ if (err_1 instanceof ClientError) {
1629
+ throw err_1;
1630
+ }
1631
+
1632
+ return [3
1633
+ /*break*/
1634
+ , 5];
1635
+
1636
+ case 5:
1637
+ return [2
1638
+ /*return*/
1639
+ ];
1640
+ }
1641
+ });
1642
+ });
1643
+ };
1644
+
1645
+ FeatureFlagsPoller.prototype._requestFeatureFlagDefinitions = function () {
1646
+ return __awaiter(this, void 0, void 0, function () {
1647
+ var url, headers, options, res, err_2;
1648
+ return __generator(this, function (_a) {
1649
+ switch (_a.label) {
1650
+ case 0:
1651
+ url = "".concat(this.host, "/api/feature_flag/local_evaluation?token=").concat(this.projectApiKey);
1652
+ headers = {
1653
+ 'Content-Type': 'application/json',
1654
+ Authorization: "Bearer ".concat(this.personalApiKey),
1655
+ 'user-agent': "posthog-node/".concat(version)
1656
+ };
1657
+ options = {
1658
+ method: 'GET',
1659
+ headers: headers
1660
+ };
1661
+
1662
+ if (this.timeout && typeof this.timeout === 'number') {
1663
+ options.bodyTimeout = this.timeout;
1664
+ }
1665
+
1666
+ _a.label = 1;
1667
+
1668
+ case 1:
1669
+ _a.trys.push([1, 3,, 4]);
1670
+
1671
+ return [4
1672
+ /*yield*/
1673
+ , undici.request(url, options)];
1674
+
1675
+ case 2:
1676
+ res = _a.sent();
1677
+ return [3
1678
+ /*break*/
1679
+ , 4];
1680
+
1681
+ case 3:
1682
+ err_2 = _a.sent();
1683
+ throw new Error("Request failed with error: ".concat(err_2));
1684
+
1685
+ case 4:
1686
+ return [2
1687
+ /*return*/
1688
+ , res];
1689
+ }
1690
+ });
1691
+ });
1692
+ };
1693
+
1694
+ FeatureFlagsPoller.prototype.stopPoller = function () {
1695
+ clearTimeout(this.poller);
1696
+ };
1697
+
1698
+ return FeatureFlagsPoller;
1699
+ }(); // # This function takes a distinct_id and a feature flag key and returns a float between 0 and 1.
1700
+ // # Given the same distinct_id and key, it'll always return the same float. These floats are
1701
+ // # uniformly distributed between 0 and 1, so if we want to show this feature to 20% of traffic
1702
+ // # we can do _hash(key, distinct_id) < 0.2
1703
+
1704
+
1705
+ function _hash(key, distinctId, salt) {
1706
+ if (salt === void 0) {
1707
+ salt = '';
1708
+ }
1709
+
1710
+ var sha1Hash = crypto.createHash('sha1');
1711
+ sha1Hash.update("".concat(key, ".").concat(distinctId).concat(salt));
1712
+ return parseInt(sha1Hash.digest('hex').slice(0, 15), 16) / LONG_SCALE;
1713
+ }
1714
+
1715
+ function matchProperty(property, propertyValues) {
1716
+ var key = property.key;
1717
+ var value = property.value;
1718
+ var operator = property.operator || 'exact';
1719
+
1720
+ if (!(key in propertyValues)) {
1721
+ throw new InconclusiveMatchError("Property ".concat(key, " not found in propertyValues"));
1722
+ } else if (operator === 'is_not_set') {
1723
+ throw new InconclusiveMatchError("Operator is_not_set is not supported");
1724
+ }
1725
+
1726
+ var overrideValue = propertyValues[key];
1727
+
1728
+ switch (operator) {
1729
+ case 'exact':
1730
+ return Array.isArray(value) ? value.indexOf(overrideValue) !== -1 : value === overrideValue;
1731
+
1732
+ case 'is_not':
1733
+ return Array.isArray(value) ? value.indexOf(overrideValue) === -1 : value !== overrideValue;
1734
+
1735
+ case 'is_set':
1736
+ return key in propertyValues;
1737
+
1738
+ case 'icontains':
1739
+ return String(overrideValue).toLowerCase().includes(String(value).toLowerCase());
1740
+
1741
+ case 'not_icontains':
1742
+ return !String(overrideValue).toLowerCase().includes(String(value).toLowerCase());
1743
+
1744
+ case 'regex':
1745
+ return isValidRegex(String(value)) && String(overrideValue).match(String(value)) !== null;
1746
+
1747
+ case 'not_regex':
1748
+ return isValidRegex(String(value)) && String(overrideValue).match(String(value)) === null;
1749
+
1750
+ case 'gt':
1751
+ return typeof overrideValue == typeof value && overrideValue > value;
1752
+
1753
+ case 'gte':
1754
+ return typeof overrideValue == typeof value && overrideValue >= value;
1755
+
1756
+ case 'lt':
1757
+ return typeof overrideValue == typeof value && overrideValue < value;
1758
+
1759
+ case 'lte':
1760
+ return typeof overrideValue == typeof value && overrideValue <= value;
1761
+
1762
+ default:
1763
+ console.error("Unknown operator: ".concat(operator));
1764
+ return false;
1765
+ }
1766
+ }
1767
+
1768
+ function isValidRegex(regex) {
1769
+ try {
1770
+ new RegExp(regex);
1771
+ return true;
1772
+ } catch (err) {
1773
+ return false;
1774
+ }
1775
+ }
1776
+
1777
+ var THIRTY_SECONDS = 30 * 1000;
1778
+ var MAX_CACHE_SIZE = 50 * 1000;
1779
+
1149
1780
  var PostHog =
1150
1781
  /** @class */
1151
1782
  function (_super) {
@@ -1161,6 +1792,8 @@ function (_super) {
1161
1792
  options.captureMode = (options === null || options === void 0 ? void 0 : options.captureMode) || 'json';
1162
1793
  options.preloadFeatureFlags = false; // Don't preload as this makes no sense without a distinctId
1163
1794
 
1795
+ options.sendFeatureFlagEvent = false; // Let `posthog-node` handle this on its own, since we're dealing with multiple distinctIDs
1796
+
1164
1797
  _this = _super.call(this, apiKey, options) || this;
1165
1798
  _this._memoryStorage = new PostHogMemoryStorage();
1166
1799
  return _this;
@@ -1207,20 +1840,25 @@ function () {
1207
1840
  options = {};
1208
1841
  }
1209
1842
 
1210
- options.decidePollInterval = 0; // Forcefully set to 0 so we don't auto-reload
1211
-
1212
1843
  this._sharedClient = new PostHog(apiKey, options);
1844
+
1845
+ if (options.personalApiKey) {
1846
+ this.featureFlagsPoller = new FeatureFlagsPoller({
1847
+ pollingInterval: typeof options.featureFlagsPollingInterval === 'number' ? options.featureFlagsPollingInterval : THIRTY_SECONDS,
1848
+ personalApiKey: options.personalApiKey,
1849
+ projectApiKey: apiKey,
1850
+ timeout: options.requestTimeout,
1851
+ host: this._sharedClient.host
1852
+ });
1853
+ }
1854
+
1855
+ this.distinctIdHasSentFlagCalls = {};
1856
+ this.maxCacheSize = options.maxCacheSize || MAX_CACHE_SIZE;
1213
1857
  }
1214
1858
 
1215
1859
  PostHogGlobal.prototype.reInit = function (distinctId) {
1216
- // Certain properties we want to persist
1217
- var propertiesToKeep = [PostHogPersistedProperty.Queue, PostHogPersistedProperty.OptedOut];
1218
-
1219
- for (var key in PostHogPersistedProperty) {
1220
- if (!propertiesToKeep.includes(key)) {
1221
- this._sharedClient.setPersistedProperty(PostHogPersistedProperty[key], null);
1222
- }
1223
- }
1860
+ // Certain properties we want to persist. Queue is persisted always by default.
1861
+ this._sharedClient.reset([PostHogPersistedProperty.OptedOut]);
1224
1862
 
1225
1863
  this._sharedClient.setPersistedProperty(PostHogPersistedProperty.DistinctId, distinctId);
1226
1864
  };
@@ -1237,14 +1875,15 @@ function () {
1237
1875
  var distinctId = _a.distinctId,
1238
1876
  event = _a.event,
1239
1877
  properties = _a.properties,
1240
- groups = _a.groups;
1878
+ groups = _a.groups,
1879
+ sendFeatureFlags = _a.sendFeatureFlags;
1241
1880
  this.reInit(distinctId);
1242
1881
 
1243
1882
  if (groups) {
1244
1883
  this._sharedClient.groups(groups);
1245
1884
  }
1246
1885
 
1247
- this._sharedClient.capture(event, properties);
1886
+ this._sharedClient.capture(event, properties, sendFeatureFlags || false);
1248
1887
  };
1249
1888
 
1250
1889
  PostHogGlobal.prototype.identify = function (_a) {
@@ -1261,33 +1900,95 @@ function () {
1261
1900
  this._sharedClient.alias(data.alias);
1262
1901
  };
1263
1902
 
1264
- PostHogGlobal.prototype.getFeatureFlag = function (key, distinctId, groups) {
1903
+ PostHogGlobal.prototype.getFeatureFlag = function (key, distinctId, options) {
1904
+ var _a;
1905
+
1265
1906
  return __awaiter(this, void 0, void 0, function () {
1266
- return __generator(this, function (_a) {
1267
- switch (_a.label) {
1907
+ var _b, groups, personProperties, groupProperties, _c, onlyEvaluateLocally, sendFeatureFlagEvents, response, flagWasLocallyEvaluated, featureFlagReportedKey;
1908
+
1909
+ return __generator(this, function (_d) {
1910
+ switch (_d.label) {
1268
1911
  case 0:
1912
+ _b = options || {}, groups = _b.groups, personProperties = _b.personProperties, groupProperties = _b.groupProperties;
1913
+ _c = options || {}, onlyEvaluateLocally = _c.onlyEvaluateLocally, sendFeatureFlagEvents = _c.sendFeatureFlagEvents; // set defaults
1914
+
1915
+ if (onlyEvaluateLocally == undefined) {
1916
+ onlyEvaluateLocally = false;
1917
+ }
1918
+
1919
+ if (sendFeatureFlagEvents == undefined) {
1920
+ sendFeatureFlagEvents = true;
1921
+ }
1922
+
1923
+ return [4
1924
+ /*yield*/
1925
+ , (_a = this.featureFlagsPoller) === null || _a === void 0 ? void 0 : _a.getFeatureFlag(key, distinctId, groups, personProperties, groupProperties)];
1926
+
1927
+ case 1:
1928
+ response = _d.sent();
1929
+ flagWasLocallyEvaluated = response !== undefined;
1930
+ if (!(!flagWasLocallyEvaluated && !onlyEvaluateLocally)) return [3
1931
+ /*break*/
1932
+ , 3];
1269
1933
  this.reInit(distinctId);
1270
1934
 
1271
- if (groups) {
1935
+ if (groups != undefined) {
1272
1936
  this._sharedClient.groups(groups);
1273
1937
  }
1274
1938
 
1939
+ if (personProperties) {
1940
+ this._sharedClient.personProperties(personProperties);
1941
+ }
1942
+
1943
+ if (groupProperties) {
1944
+ this._sharedClient.groupProperties(groupProperties);
1945
+ }
1946
+
1275
1947
  return [4
1276
1948
  /*yield*/
1277
- , this._sharedClient.reloadFeatureFlagsAsync()];
1949
+ , this._sharedClient.reloadFeatureFlagsAsync(false)];
1278
1950
 
1279
- case 1:
1280
- _a.sent();
1951
+ case 2:
1952
+ _d.sent();
1953
+
1954
+ response = this._sharedClient.getFeatureFlag(key);
1955
+ _d.label = 3;
1956
+
1957
+ case 3:
1958
+ featureFlagReportedKey = "".concat(key, "_").concat(response);
1959
+
1960
+ if (sendFeatureFlagEvents && (!(distinctId in this.distinctIdHasSentFlagCalls) || !this.distinctIdHasSentFlagCalls[distinctId].includes(featureFlagReportedKey))) {
1961
+ if (Object.keys(this.distinctIdHasSentFlagCalls).length >= this.maxCacheSize) {
1962
+ this.distinctIdHasSentFlagCalls = {};
1963
+ }
1964
+
1965
+ if (Array.isArray(this.distinctIdHasSentFlagCalls[distinctId])) {
1966
+ this.distinctIdHasSentFlagCalls[distinctId].push(featureFlagReportedKey);
1967
+ } else {
1968
+ this.distinctIdHasSentFlagCalls[distinctId] = [featureFlagReportedKey];
1969
+ }
1970
+
1971
+ this.capture({
1972
+ distinctId: distinctId,
1973
+ event: '$feature_flag_called',
1974
+ properties: {
1975
+ $feature_flag: key,
1976
+ $feature_flag_response: response,
1977
+ locally_evaluated: flagWasLocallyEvaluated
1978
+ },
1979
+ groups: groups
1980
+ });
1981
+ }
1281
1982
 
1282
1983
  return [2
1283
1984
  /*return*/
1284
- , this._sharedClient.getFeatureFlag(key)];
1985
+ , response];
1285
1986
  }
1286
1987
  });
1287
1988
  });
1288
1989
  };
1289
1990
 
1290
- PostHogGlobal.prototype.isFeatureEnabled = function (key, distinctId, defaultResult, groups) {
1991
+ PostHogGlobal.prototype.isFeatureEnabled = function (key, distinctId, options) {
1291
1992
  return __awaiter(this, void 0, void 0, function () {
1292
1993
  var feat;
1293
1994
  return __generator(this, function (_a) {
@@ -1295,13 +1996,88 @@ function () {
1295
1996
  case 0:
1296
1997
  return [4
1297
1998
  /*yield*/
1298
- , this.getFeatureFlag(key, distinctId, groups)];
1999
+ , this.getFeatureFlag(key, distinctId, options)];
1299
2000
 
1300
2001
  case 1:
1301
2002
  feat = _a.sent();
2003
+
2004
+ if (feat === undefined) {
2005
+ return [2
2006
+ /*return*/
2007
+ , undefined];
2008
+ }
2009
+
1302
2010
  return [2
1303
2011
  /*return*/
1304
- , !!feat || defaultResult || false];
2012
+ , !!feat || false];
2013
+ }
2014
+ });
2015
+ });
2016
+ };
2017
+
2018
+ PostHogGlobal.prototype.getAllFlags = function (distinctId, options) {
2019
+ var _a;
2020
+
2021
+ return __awaiter(this, void 0, void 0, function () {
2022
+ var _b, groups, personProperties, groupProperties, onlyEvaluateLocally, localEvaluationResult, response, fallbackToDecide, remoteEvaluationResult;
2023
+
2024
+ return __generator(this, function (_c) {
2025
+ switch (_c.label) {
2026
+ case 0:
2027
+ _b = options || {}, groups = _b.groups, personProperties = _b.personProperties, groupProperties = _b.groupProperties;
2028
+ onlyEvaluateLocally = (options || {}).onlyEvaluateLocally; // set defaults
2029
+
2030
+ if (onlyEvaluateLocally == undefined) {
2031
+ onlyEvaluateLocally = false;
2032
+ }
2033
+
2034
+ return [4
2035
+ /*yield*/
2036
+ , (_a = this.featureFlagsPoller) === null || _a === void 0 ? void 0 : _a.getAllFlags(distinctId, groups, personProperties, groupProperties)];
2037
+
2038
+ case 1:
2039
+ localEvaluationResult = _c.sent();
2040
+ response = {};
2041
+ fallbackToDecide = true;
2042
+
2043
+ if (localEvaluationResult) {
2044
+ response = localEvaluationResult.response;
2045
+ fallbackToDecide = localEvaluationResult.fallbackToDecide;
2046
+ }
2047
+
2048
+ if (!(fallbackToDecide && !onlyEvaluateLocally)) return [3
2049
+ /*break*/
2050
+ , 3];
2051
+ this.reInit(distinctId);
2052
+
2053
+ if (groups) {
2054
+ this._sharedClient.groups(groups);
2055
+ }
2056
+
2057
+ if (personProperties) {
2058
+ this._sharedClient.personProperties(personProperties);
2059
+ }
2060
+
2061
+ if (groupProperties) {
2062
+ this._sharedClient.groupProperties(groupProperties);
2063
+ }
2064
+
2065
+ return [4
2066
+ /*yield*/
2067
+ , this._sharedClient.reloadFeatureFlagsAsync(false)];
2068
+
2069
+ case 2:
2070
+ _c.sent();
2071
+
2072
+ remoteEvaluationResult = this._sharedClient.getFeatureFlags();
2073
+ return [2
2074
+ /*return*/
2075
+ , __assign(__assign({}, response), remoteEvaluationResult)];
2076
+
2077
+ case 3:
2078
+ return [2
2079
+ /*return*/
2080
+ , response];
1305
2081
  }
1306
2082
  });
1307
2083
  });
@@ -1316,15 +2092,50 @@ function () {
1316
2092
  };
1317
2093
 
1318
2094
  PostHogGlobal.prototype.reloadFeatureFlags = function () {
1319
- throw new Error('Method not implemented.');
2095
+ var _a;
2096
+
2097
+ return __awaiter(this, void 0, void 0, function () {
2098
+ return __generator(this, function (_b) {
2099
+ switch (_b.label) {
2100
+ case 0:
2101
+ return [4
2102
+ /*yield*/
2103
+ , (_a = this.featureFlagsPoller) === null || _a === void 0 ? void 0 : _a.loadFeatureFlags(true)];
2104
+
2105
+ case 1:
2106
+ _b.sent();
2107
+
2108
+ return [2
2109
+ /*return*/
2110
+ ];
2111
+ }
2112
+ });
2113
+ });
2114
+ };
2115
+
2116
+ PostHogGlobal.prototype.flush = function () {
2117
+ this._sharedClient.flush();
1320
2118
  };
1321
2119
 
1322
2120
  PostHogGlobal.prototype.shutdown = function () {
1323
- void this._sharedClient.shutdownAsync();
2121
+ void this.shutdownAsync();
1324
2122
  };
1325
2123
 
1326
2124
  PostHogGlobal.prototype.shutdownAsync = function () {
1327
- return this._sharedClient.shutdownAsync();
2125
+ var _a;
2126
+
2127
+ return __awaiter(this, void 0, void 0, function () {
2128
+ return __generator(this, function (_b) {
2129
+ (_a = this.featureFlagsPoller) === null || _a === void 0 ? void 0 : _a.stopPoller();
2130
+ return [2
2131
+ /*return*/
2132
+ , this._sharedClient.shutdownAsync()];
2133
+ });
2134
+ });
2135
+ };
2136
+
2137
+ PostHogGlobal.prototype.debug = function (enabled) {
2138
+ return this._sharedClient.debug(enabled);
1328
2139
  };
1329
2140
 
1330
2141
  return PostHogGlobal;