posthog-node 4.0.0-beta.3 → 4.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/CHANGELOG.md +30 -0
- package/lib/index.cjs.js +33 -21
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +6 -1
- package/lib/index.esm.js +33 -21
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-core/src/index.d.ts +1 -0
- package/lib/posthog-core/src/types.d.ts +5 -1
- package/lib/posthog-node/src/types.d.ts +1 -1
- package/package.json +1 -1
- package/src/feature-flags.ts +20 -10
- package/src/posthog-node.ts +1 -6
- package/src/types.ts +1 -1
- package/test/posthog-node.spec.ts +69 -7
- package/test/test-utils.ts +3 -1
package/lib/index.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ declare type PostHogCoreOptions = {
|
|
|
8
8
|
flushInterval?: number;
|
|
9
9
|
/** The maximum number of queued messages to be flushed as part of a single batch (must be higher than `flushAt`) */
|
|
10
10
|
maxBatchSize?: number;
|
|
11
|
+
/** The maximum number of cached messages either in memory or on the local storage.
|
|
12
|
+
* Defaults to 1000, (must be higher than `flushAt`)
|
|
13
|
+
*/
|
|
14
|
+
maxQueueSize?: number;
|
|
11
15
|
/** If set to true the SDK is essentially disabled (useful for local environments where you don't want to track anything) */
|
|
12
16
|
disabled?: boolean;
|
|
13
17
|
/** If set to false the SDK will not track until the `optIn` function is called. */
|
|
@@ -33,7 +37,7 @@ declare type PostHogCoreOptions = {
|
|
|
33
37
|
featureFlagsRequestTimeoutMs?: number;
|
|
34
38
|
/** For Session Analysis how long before we expire a session (defaults to 30 mins) */
|
|
35
39
|
sessionExpirationTimeSeconds?: number;
|
|
36
|
-
/** Whether to post events to PostHog in JSON or compressed format */
|
|
40
|
+
/** Whether to post events to PostHog in JSON or compressed format. Defaults to 'form' */
|
|
37
41
|
captureMode?: 'json' | 'form';
|
|
38
42
|
disableGeoip?: boolean;
|
|
39
43
|
};
|
|
@@ -125,6 +129,7 @@ declare abstract class PostHogCoreStateless {
|
|
|
125
129
|
host: string;
|
|
126
130
|
private flushAt;
|
|
127
131
|
private maxBatchSize;
|
|
132
|
+
private maxQueueSize;
|
|
128
133
|
private flushInterval;
|
|
129
134
|
private flushPromise;
|
|
130
135
|
private requestTimeout;
|
package/lib/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'rusha';
|
|
2
2
|
|
|
3
|
-
var version = "4.0.
|
|
3
|
+
var version = "4.0.1";
|
|
4
4
|
|
|
5
5
|
var PostHogPersistedProperty;
|
|
6
6
|
(function (PostHogPersistedProperty) {
|
|
@@ -959,6 +959,7 @@ class PostHogCoreStateless {
|
|
|
959
959
|
this.host = removeTrailingSlash(options?.host || 'https://app.posthog.com');
|
|
960
960
|
this.flushAt = options?.flushAt ? Math.max(options?.flushAt, 1) : 20;
|
|
961
961
|
this.maxBatchSize = Math.max(this.flushAt, options?.maxBatchSize ?? 100);
|
|
962
|
+
this.maxQueueSize = Math.max(this.flushAt, options?.maxQueueSize ?? 1000);
|
|
962
963
|
this.flushInterval = options?.flushInterval ?? 10000;
|
|
963
964
|
this.captureMode = options?.captureMode || 'form';
|
|
964
965
|
// If enable is explicitly set to false we override the optout
|
|
@@ -1152,14 +1153,11 @@ class PostHogCoreStateless {
|
|
|
1152
1153
|
if (response === undefined) {
|
|
1153
1154
|
return null;
|
|
1154
1155
|
}
|
|
1155
|
-
return
|
|
1156
|
+
return response;
|
|
1156
1157
|
}
|
|
1157
1158
|
async getFeatureFlagPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1158
1159
|
await this._initPromise;
|
|
1159
1160
|
const payloads = (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)).payloads;
|
|
1160
|
-
if (payloads) {
|
|
1161
|
-
return Object.fromEntries(Object.entries(payloads).map(([k, v]) => [k, this._parsePayload(v)]));
|
|
1162
|
-
}
|
|
1163
1161
|
return payloads;
|
|
1164
1162
|
}
|
|
1165
1163
|
_parsePayload(response) {
|
|
@@ -1183,9 +1181,13 @@ class PostHogCoreStateless {
|
|
|
1183
1181
|
const decideResponse = await this.getDecide(distinctId, groups, personProperties, groupProperties, extraPayload);
|
|
1184
1182
|
const flags = decideResponse?.featureFlags;
|
|
1185
1183
|
const payloads = decideResponse?.featureFlagPayloads;
|
|
1184
|
+
let parsedPayloads = payloads;
|
|
1185
|
+
if (payloads) {
|
|
1186
|
+
parsedPayloads = Object.fromEntries(Object.entries(payloads).map(([k, v]) => [k, this._parsePayload(v)]));
|
|
1187
|
+
}
|
|
1186
1188
|
return {
|
|
1187
1189
|
flags,
|
|
1188
|
-
payloads,
|
|
1190
|
+
payloads: parsedPayloads,
|
|
1189
1191
|
};
|
|
1190
1192
|
}
|
|
1191
1193
|
/***
|
|
@@ -1217,6 +1219,10 @@ class PostHogCoreStateless {
|
|
|
1217
1219
|
delete message.distinctId;
|
|
1218
1220
|
}
|
|
1219
1221
|
const queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
|
|
1222
|
+
if (queue.length >= this.maxQueueSize) {
|
|
1223
|
+
queue.shift();
|
|
1224
|
+
console.info('Queue is full, the oldest event is dropped.');
|
|
1225
|
+
}
|
|
1220
1226
|
queue.push({ message });
|
|
1221
1227
|
this.setPersistedProperty(PostHogPersistedProperty.Queue, queue);
|
|
1222
1228
|
this._events.emit(type, message);
|
|
@@ -1534,11 +1540,15 @@ class FeatureFlagsPoller {
|
|
|
1534
1540
|
} // Undefined means a loading or missing data issue. Null means evaluation happened and there was no match
|
|
1535
1541
|
|
|
1536
1542
|
|
|
1537
|
-
if (response === undefined) {
|
|
1543
|
+
if (response === undefined || response === null) {
|
|
1538
1544
|
return null;
|
|
1539
1545
|
}
|
|
1540
1546
|
|
|
1541
|
-
|
|
1547
|
+
try {
|
|
1548
|
+
return JSON.parse(response);
|
|
1549
|
+
} catch {
|
|
1550
|
+
return response;
|
|
1551
|
+
}
|
|
1542
1552
|
}
|
|
1543
1553
|
|
|
1544
1554
|
async getAllFlagsAndPayloads(distinctId, groups = {}, personProperties = {}, groupProperties = {}) {
|
|
@@ -1672,7 +1682,7 @@ class FeatureFlagsPoller {
|
|
|
1672
1682
|
let matches = false;
|
|
1673
1683
|
|
|
1674
1684
|
if (propertyType === 'cohort') {
|
|
1675
|
-
matches = matchCohort(prop, properties, this.cohorts);
|
|
1685
|
+
matches = matchCohort(prop, properties, this.cohorts, this.debugMode);
|
|
1676
1686
|
} else {
|
|
1677
1687
|
matches = matchProperty(prop, properties);
|
|
1678
1688
|
}
|
|
@@ -1928,7 +1938,7 @@ function matchProperty(property, propertyValues) {
|
|
|
1928
1938
|
}
|
|
1929
1939
|
}
|
|
1930
1940
|
|
|
1931
|
-
function matchCohort(property, propertyValues, cohortProperties) {
|
|
1941
|
+
function matchCohort(property, propertyValues, cohortProperties, debugMode = false) {
|
|
1932
1942
|
const cohortId = String(property.value);
|
|
1933
1943
|
|
|
1934
1944
|
if (!(cohortId in cohortProperties)) {
|
|
@@ -1936,10 +1946,10 @@ function matchCohort(property, propertyValues, cohortProperties) {
|
|
|
1936
1946
|
}
|
|
1937
1947
|
|
|
1938
1948
|
const propertyGroup = cohortProperties[cohortId];
|
|
1939
|
-
return matchPropertyGroup(propertyGroup, propertyValues, cohortProperties);
|
|
1949
|
+
return matchPropertyGroup(propertyGroup, propertyValues, cohortProperties, debugMode);
|
|
1940
1950
|
}
|
|
1941
1951
|
|
|
1942
|
-
function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties) {
|
|
1952
|
+
function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties, debugMode = false) {
|
|
1943
1953
|
if (!propertyGroup) {
|
|
1944
1954
|
return true;
|
|
1945
1955
|
}
|
|
@@ -1958,7 +1968,7 @@ function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties) {
|
|
|
1958
1968
|
// a nested property group
|
|
1959
1969
|
for (const prop of properties) {
|
|
1960
1970
|
try {
|
|
1961
|
-
const matches = matchPropertyGroup(prop, propertyValues, cohortProperties);
|
|
1971
|
+
const matches = matchPropertyGroup(prop, propertyValues, cohortProperties, debugMode);
|
|
1962
1972
|
|
|
1963
1973
|
if (propertyGroupType === 'AND') {
|
|
1964
1974
|
if (!matches) {
|
|
@@ -1972,7 +1982,10 @@ function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties) {
|
|
|
1972
1982
|
}
|
|
1973
1983
|
} catch (err) {
|
|
1974
1984
|
if (err instanceof InconclusiveMatchError) {
|
|
1975
|
-
|
|
1985
|
+
if (debugMode) {
|
|
1986
|
+
console.debug(`Failed to compute property ${prop} locally: ${err}`);
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1976
1989
|
errorMatchingLocally = true;
|
|
1977
1990
|
} else {
|
|
1978
1991
|
throw err;
|
|
@@ -1992,7 +2005,7 @@ function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties) {
|
|
|
1992
2005
|
let matches;
|
|
1993
2006
|
|
|
1994
2007
|
if (prop.type === 'cohort') {
|
|
1995
|
-
matches = matchCohort(prop, propertyValues, cohortProperties);
|
|
2008
|
+
matches = matchCohort(prop, propertyValues, cohortProperties, debugMode);
|
|
1996
2009
|
} else {
|
|
1997
2010
|
matches = matchProperty(prop, propertyValues);
|
|
1998
2011
|
}
|
|
@@ -2020,7 +2033,10 @@ function matchPropertyGroup(propertyGroup, propertyValues, cohortProperties) {
|
|
|
2020
2033
|
}
|
|
2021
2034
|
} catch (err) {
|
|
2022
2035
|
if (err instanceof InconclusiveMatchError) {
|
|
2023
|
-
|
|
2036
|
+
if (debugMode) {
|
|
2037
|
+
console.debug(`Failed to compute property ${prop} locally: ${err}`);
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2024
2040
|
errorMatchingLocally = true;
|
|
2025
2041
|
} else {
|
|
2026
2042
|
throw err;
|
|
@@ -2369,11 +2385,7 @@ class PostHog extends PostHogCoreStateless {
|
|
|
2369
2385
|
response = await super.getFeatureFlagPayloadStateless(key, distinctId, groups, personProperties, groupProperties, disableGeoip);
|
|
2370
2386
|
}
|
|
2371
2387
|
|
|
2372
|
-
|
|
2373
|
-
return JSON.parse(response);
|
|
2374
|
-
} catch {
|
|
2375
|
-
return response;
|
|
2376
|
-
}
|
|
2388
|
+
return response;
|
|
2377
2389
|
}
|
|
2378
2390
|
|
|
2379
2391
|
async isFeatureEnabled(key, distinctId, options) {
|