posthog-node 5.8.2 → 5.8.4
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/edge/index.cjs +26 -17
- package/dist/edge/index.cjs.map +1 -1
- package/dist/edge/index.mjs +26 -17
- package/dist/edge/index.mjs.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/node/index.cjs +26 -17
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.mjs +26 -17
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/edge/index.mjs
CHANGED
|
@@ -22,13 +22,15 @@ import { PostHogCoreStateless, getFeatureFlagValue, safeSetTimeout as safeSetTim
|
|
|
22
22
|
* @param {Number} [projectId] Optional: The Sentry project id, used to send a direct link from PostHog to Sentry
|
|
23
23
|
* @param {string} [prefix] Optional: Url of a self-hosted sentry instance (default: https://sentry.io/organizations/)
|
|
24
24
|
* @param {SeverityLevel[] | '*'} [severityAllowList] Optional: send events matching the provided levels. Use '*' to send all events (default: ['error'])
|
|
25
|
+
* @param {boolean} [sendExceptionsToPostHog] Optional: capture exceptions as events in PostHog (default: true)
|
|
25
26
|
*/
|
|
26
27
|
const NAME = 'posthog-node';
|
|
27
28
|
function createEventProcessor(_posthog, {
|
|
28
29
|
organization,
|
|
29
30
|
projectId,
|
|
30
31
|
prefix,
|
|
31
|
-
severityAllowList = ['error']
|
|
32
|
+
severityAllowList = ['error'],
|
|
33
|
+
sendExceptionsToPostHog = true
|
|
32
34
|
} = {}) {
|
|
33
35
|
return event => {
|
|
34
36
|
const shouldProcessLevel = severityAllowList === '*' || severityAllowList.includes(event.level);
|
|
@@ -78,11 +80,13 @@ function createEventProcessor(_posthog, {
|
|
|
78
80
|
if (organization && projectId) {
|
|
79
81
|
properties['$sentry_url'] = (prefix || 'https://sentry.io/organizations/') + organization + '/issues/?project=' + projectId + '&query=' + event.event_id;
|
|
80
82
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
if (sendExceptionsToPostHog) {
|
|
84
|
+
_posthog.capture({
|
|
85
|
+
event: '$exception',
|
|
86
|
+
distinctId: userId,
|
|
87
|
+
properties
|
|
88
|
+
});
|
|
89
|
+
}
|
|
86
90
|
return event;
|
|
87
91
|
};
|
|
88
92
|
}
|
|
@@ -98,7 +102,7 @@ function sentryIntegration(_posthog, options) {
|
|
|
98
102
|
}
|
|
99
103
|
// V7 integration - class based
|
|
100
104
|
class PostHogSentryIntegration {
|
|
101
|
-
constructor(_posthog, organization, prefix, severityAllowList) {
|
|
105
|
+
constructor(_posthog, organization, prefix, severityAllowList, sendExceptionsToPostHog) {
|
|
102
106
|
this.name = NAME;
|
|
103
107
|
// setupOnce gets called by Sentry when it intializes the plugin
|
|
104
108
|
this.name = NAME;
|
|
@@ -108,7 +112,8 @@ class PostHogSentryIntegration {
|
|
|
108
112
|
organization,
|
|
109
113
|
projectId,
|
|
110
114
|
prefix,
|
|
111
|
-
severityAllowList
|
|
115
|
+
severityAllowList,
|
|
116
|
+
sendExceptionsToPostHog: sendExceptionsToPostHog ?? true
|
|
112
117
|
}));
|
|
113
118
|
};
|
|
114
119
|
}
|
|
@@ -778,7 +783,7 @@ function setupExpressErrorHandler(_posthog, app) {
|
|
|
778
783
|
});
|
|
779
784
|
}
|
|
780
785
|
|
|
781
|
-
var version = "5.8.
|
|
786
|
+
var version = "5.8.4";
|
|
782
787
|
|
|
783
788
|
/**
|
|
784
789
|
* A lazy value that is only computed when needed. Inspired by C#'s Lazy<T> class.
|
|
@@ -965,12 +970,14 @@ class FeatureFlagsPoller {
|
|
|
965
970
|
const payloads = {};
|
|
966
971
|
let fallbackToFlags = this.featureFlags.length == 0;
|
|
967
972
|
const flagsToEvaluate = flagKeysToExplicitlyEvaluate ? flagKeysToExplicitlyEvaluate.map(key => this.featureFlagsByKey[key]).filter(Boolean) : this.featureFlags;
|
|
973
|
+
// Create a shared evaluation cache to prevent memory leaks when processing many flags
|
|
974
|
+
const sharedEvaluationCache = {};
|
|
968
975
|
await Promise.all(flagsToEvaluate.map(async flag => {
|
|
969
976
|
try {
|
|
970
977
|
const {
|
|
971
978
|
value: matchValue,
|
|
972
979
|
payload: matchPayload
|
|
973
|
-
} = await this.computeFlagAndPayloadLocally(flag, distinctId, groups, personProperties, groupProperties);
|
|
980
|
+
} = await this.computeFlagAndPayloadLocally(flag, distinctId, groups, personProperties, groupProperties, undefined /* matchValue */, sharedEvaluationCache);
|
|
974
981
|
response[flag.key] = matchValue;
|
|
975
982
|
if (matchPayload) {
|
|
976
983
|
payloads[flag.key] = matchPayload;
|
|
@@ -990,9 +997,11 @@ class FeatureFlagsPoller {
|
|
|
990
997
|
fallbackToFlags
|
|
991
998
|
};
|
|
992
999
|
}
|
|
993
|
-
async computeFlagAndPayloadLocally(flag, distinctId, groups = {}, personProperties = {}, groupProperties = {}, matchValue) {
|
|
994
|
-
//
|
|
995
|
-
|
|
1000
|
+
async computeFlagAndPayloadLocally(flag, distinctId, groups = {}, personProperties = {}, groupProperties = {}, matchValue, evaluationCache, skipLoadCheck = false) {
|
|
1001
|
+
// Only load flags if not already loaded and not skipping the check
|
|
1002
|
+
if (!skipLoadCheck) {
|
|
1003
|
+
await this.loadFeatureFlags();
|
|
1004
|
+
}
|
|
996
1005
|
if (!this.loadedSuccessfullyOnce) {
|
|
997
1006
|
return {
|
|
998
1007
|
value: false,
|
|
@@ -1004,7 +1013,7 @@ class FeatureFlagsPoller {
|
|
|
1004
1013
|
if (matchValue !== undefined) {
|
|
1005
1014
|
flagValue = matchValue;
|
|
1006
1015
|
} else {
|
|
1007
|
-
flagValue = await this.computeFlagValueLocally(flag, distinctId, groups, personProperties, groupProperties);
|
|
1016
|
+
flagValue = await this.computeFlagValueLocally(flag, distinctId, groups, personProperties, groupProperties, evaluationCache);
|
|
1008
1017
|
}
|
|
1009
1018
|
// Always compute payload based on the final flagValue (whether provided or computed)
|
|
1010
1019
|
const payload = this.getFeatureFlagPayload(flag.key, flagValue);
|
|
@@ -1013,7 +1022,7 @@ class FeatureFlagsPoller {
|
|
|
1013
1022
|
payload
|
|
1014
1023
|
};
|
|
1015
1024
|
}
|
|
1016
|
-
async computeFlagValueLocally(flag, distinctId, groups = {}, personProperties = {}, groupProperties = {}) {
|
|
1025
|
+
async computeFlagValueLocally(flag, distinctId, groups = {}, personProperties = {}, groupProperties = {}, evaluationCache = {}) {
|
|
1017
1026
|
if (flag.ensure_experience_continuity) {
|
|
1018
1027
|
throw new InconclusiveMatchError('Flag has experience continuity enabled');
|
|
1019
1028
|
}
|
|
@@ -1033,9 +1042,9 @@ class FeatureFlagsPoller {
|
|
|
1033
1042
|
return false;
|
|
1034
1043
|
}
|
|
1035
1044
|
const focusedGroupProperties = groupProperties[groupName];
|
|
1036
|
-
return await this.matchFeatureFlagProperties(flag, groups[groupName], focusedGroupProperties);
|
|
1045
|
+
return await this.matchFeatureFlagProperties(flag, groups[groupName], focusedGroupProperties, evaluationCache);
|
|
1037
1046
|
} else {
|
|
1038
|
-
return await this.matchFeatureFlagProperties(flag, distinctId, personProperties);
|
|
1047
|
+
return await this.matchFeatureFlagProperties(flag, distinctId, personProperties, evaluationCache);
|
|
1039
1048
|
}
|
|
1040
1049
|
}
|
|
1041
1050
|
getFeatureFlagPayload(key, flagValue) {
|