posthog-node 4.3.1 → 4.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 +8 -0
- package/README.md +1 -1
- package/benchmarks/rusha-vs-native.mjs +70 -0
- package/lib/index.cjs.js +34 -58
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +20 -5
- package/lib/index.esm.js +34 -58
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-core/src/types.d.ts +4 -1
- package/lib/posthog-node/src/types.d.ts +16 -4
- package/package.json +4 -4
- package/src/feature-flags.ts +2 -3
- package/src/posthog-node.ts +30 -51
- package/src/types.ts +16 -4
- package/test/posthog-node.spec.ts +2 -35
- package/tsconfig.json +2 -2
- package/src/types/rusha.d.ts +0 -23
package/lib/index.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ declare enum PostHogPersistedProperty {
|
|
|
49
49
|
Props = "props",
|
|
50
50
|
FeatureFlags = "feature_flags",
|
|
51
51
|
FeatureFlagPayloads = "feature_flag_payloads",
|
|
52
|
+
BootstrapFeatureFlags = "bootstrap_feature_flags",
|
|
53
|
+
BootstrapFeatureFlagPayloads = "bootstrap_feature_flag_payloads",
|
|
52
54
|
OverrideFeatureFlags = "override_feature_flags",
|
|
53
55
|
Queue = "queue",
|
|
54
56
|
OptedOut = "opted_out",
|
|
@@ -58,7 +60,8 @@ declare enum PostHogPersistedProperty {
|
|
|
58
60
|
GroupProperties = "group_properties",
|
|
59
61
|
InstalledAppBuild = "installed_app_build",
|
|
60
62
|
InstalledAppVersion = "installed_app_version",
|
|
61
|
-
SessionReplay = "session_replay"
|
|
63
|
+
SessionReplay = "session_replay",
|
|
64
|
+
DecideEndpointWasHit = "decide_endpoint_was_hit"
|
|
62
65
|
}
|
|
63
66
|
type PostHogFetchOptions = {
|
|
64
67
|
method: 'GET' | 'POST' | 'PUT' | 'PATCH';
|
|
@@ -319,13 +322,25 @@ type PostHogNodeV1 = {
|
|
|
319
322
|
}): Promise<string | boolean | undefined>;
|
|
320
323
|
/**
|
|
321
324
|
* @description Retrieves payload associated with the specified flag and matched value that is passed in.
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
+
*
|
|
326
|
+
* IMPORTANT: The `matchValue` parameter should be the value you previously obtained from `getFeatureFlag()`.
|
|
327
|
+
* If matchValue isn't passed (or is undefined), this method will automatically call `getFeatureFlag()`
|
|
328
|
+
* internally to fetch the flag value, which could result in a network call to the PostHog server if this flag can
|
|
329
|
+
* not be evaluated locally. This means that omitting `matchValue` will potentially:
|
|
330
|
+
* - Bypass local evaluation
|
|
331
|
+
* - Count as an additional flag evaluation against your quota
|
|
332
|
+
* - Impact performance due to the extra network request
|
|
333
|
+
*
|
|
334
|
+
* Example usage:
|
|
335
|
+
* ```js
|
|
336
|
+
* const flagValue = await client.getFeatureFlag('my-flag', distinctId);
|
|
337
|
+
* const payload = await client.getFeatureFlagPayload('my-flag', distinctId, flagValue);
|
|
338
|
+
* ```
|
|
325
339
|
*
|
|
326
340
|
* @param key the unique key of your feature flag
|
|
327
341
|
* @param distinctId the current unique id
|
|
328
|
-
* @param matchValue
|
|
342
|
+
* @param matchValue The flag value previously obtained from calling `getFeatureFlag()`. Can be a string or boolean.
|
|
343
|
+
* To avoid extra network calls, pass this parameter when you can.
|
|
329
344
|
* @param options: dict with optional parameters below
|
|
330
345
|
* @param onlyEvaluateLocally optional - whether to only evaluate the flag locally. Defaults to false.
|
|
331
346
|
*
|
package/lib/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createHash } from '
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
2
|
|
|
3
|
-
var version = "4.
|
|
3
|
+
var version = "4.4.0";
|
|
4
4
|
|
|
5
5
|
var PostHogPersistedProperty;
|
|
6
6
|
(function (PostHogPersistedProperty) {
|
|
@@ -9,6 +9,8 @@ var PostHogPersistedProperty;
|
|
|
9
9
|
PostHogPersistedProperty["Props"] = "props";
|
|
10
10
|
PostHogPersistedProperty["FeatureFlags"] = "feature_flags";
|
|
11
11
|
PostHogPersistedProperty["FeatureFlagPayloads"] = "feature_flag_payloads";
|
|
12
|
+
PostHogPersistedProperty["BootstrapFeatureFlags"] = "bootstrap_feature_flags";
|
|
13
|
+
PostHogPersistedProperty["BootstrapFeatureFlagPayloads"] = "bootstrap_feature_flag_payloads";
|
|
12
14
|
PostHogPersistedProperty["OverrideFeatureFlags"] = "override_feature_flags";
|
|
13
15
|
PostHogPersistedProperty["Queue"] = "queue";
|
|
14
16
|
PostHogPersistedProperty["OptedOut"] = "opted_out";
|
|
@@ -19,6 +21,7 @@ var PostHogPersistedProperty;
|
|
|
19
21
|
PostHogPersistedProperty["InstalledAppBuild"] = "installed_app_build";
|
|
20
22
|
PostHogPersistedProperty["InstalledAppVersion"] = "installed_app_version";
|
|
21
23
|
PostHogPersistedProperty["SessionReplay"] = "session_replay";
|
|
24
|
+
PostHogPersistedProperty["DecideEndpointWasHit"] = "decide_endpoint_was_hit";
|
|
22
25
|
})(PostHogPersistedProperty || (PostHogPersistedProperty = {}));
|
|
23
26
|
|
|
24
27
|
function assert(truthyValue, message) {
|
|
@@ -1782,8 +1785,7 @@ class FeatureFlagsPoller {
|
|
|
1782
1785
|
// # uniformly distributed between 0 and 1, so if we want to show this feature to 20% of traffic
|
|
1783
1786
|
// # we can do _hash(key, distinct_id) < 0.2
|
|
1784
1787
|
function _hash(key, distinctId, salt = '') {
|
|
1785
|
-
|
|
1786
|
-
const sha1Hash = createHash();
|
|
1788
|
+
const sha1Hash = createHash('sha1');
|
|
1787
1789
|
sha1Hash.update(`${key}.${distinctId}${salt}`);
|
|
1788
1790
|
return parseInt(sha1Hash.digest('hex').slice(0, 15), 16) / LONG_SCALE;
|
|
1789
1791
|
}
|
|
@@ -2230,70 +2232,44 @@ class PostHog extends PostHogCoreStateless {
|
|
|
2230
2232
|
async getFeatureFlagPayload(key, distinctId, matchValue, options) {
|
|
2231
2233
|
const {
|
|
2232
2234
|
groups,
|
|
2233
|
-
disableGeoip
|
|
2234
|
-
|
|
2235
|
+
disableGeoip
|
|
2236
|
+
} = options || {};
|
|
2237
|
+
let {
|
|
2238
|
+
onlyEvaluateLocally,
|
|
2239
|
+
sendFeatureFlagEvents,
|
|
2235
2240
|
personProperties,
|
|
2236
2241
|
groupProperties
|
|
2237
2242
|
} = options || {};
|
|
2238
|
-
const
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
+
const adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
|
|
2244
|
+
personProperties = adjustedProperties.allPersonProperties;
|
|
2245
|
+
groupProperties = adjustedProperties.allGroupProperties;
|
|
2246
|
+
let response = undefined;
|
|
2247
|
+
// Try to get match value locally if not provided
|
|
2248
|
+
if (!matchValue) {
|
|
2243
2249
|
matchValue = await this.getFeatureFlag(key, distinctId, {
|
|
2244
2250
|
...options,
|
|
2245
|
-
onlyEvaluateLocally: true
|
|
2246
|
-
sendFeatureFlagEvents: false
|
|
2251
|
+
onlyEvaluateLocally: true
|
|
2247
2252
|
});
|
|
2248
2253
|
}
|
|
2249
|
-
let response;
|
|
2250
|
-
let payload;
|
|
2251
2254
|
if (matchValue) {
|
|
2252
|
-
response = matchValue;
|
|
2253
|
-
payload = await this.featureFlagsPoller?.computeFeatureFlagPayloadLocally(key, matchValue);
|
|
2254
|
-
} else {
|
|
2255
|
-
response = undefined;
|
|
2256
|
-
payload = undefined;
|
|
2255
|
+
response = await this.featureFlagsPoller?.computeFeatureFlagPayloadLocally(key, matchValue);
|
|
2257
2256
|
}
|
|
2258
|
-
//
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
let fetchedOrLocalFlags;
|
|
2262
|
-
let fetchedOrLocalPayloads;
|
|
2263
|
-
if (payloadWasLocallyEvaluated || onlyEvaluateLocally) {
|
|
2264
|
-
if (response !== undefined) {
|
|
2265
|
-
fetchedOrLocalFlags = {
|
|
2266
|
-
[key]: response
|
|
2267
|
-
};
|
|
2268
|
-
fetchedOrLocalPayloads = {
|
|
2269
|
-
[key]: payload
|
|
2270
|
-
};
|
|
2271
|
-
} else {
|
|
2272
|
-
fetchedOrLocalFlags = {};
|
|
2273
|
-
fetchedOrLocalPayloads = {};
|
|
2274
|
-
}
|
|
2275
|
-
} else {
|
|
2276
|
-
const fetchedData = await super.getFeatureFlagsAndPayloadsStateless(distinctId, groups, allPersonProperties, allGroupProperties, disableGeoip);
|
|
2277
|
-
fetchedOrLocalFlags = fetchedData.flags || {};
|
|
2278
|
-
fetchedOrLocalPayloads = fetchedData.payloads || {};
|
|
2257
|
+
// set defaults
|
|
2258
|
+
if (onlyEvaluateLocally == undefined) {
|
|
2259
|
+
onlyEvaluateLocally = false;
|
|
2279
2260
|
}
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
},
|
|
2293
|
-
groups,
|
|
2294
|
-
disableGeoip
|
|
2295
|
-
});
|
|
2296
|
-
return finalPayload;
|
|
2261
|
+
if (sendFeatureFlagEvents == undefined) {
|
|
2262
|
+
sendFeatureFlagEvents = true;
|
|
2263
|
+
}
|
|
2264
|
+
// set defaults
|
|
2265
|
+
if (onlyEvaluateLocally == undefined) {
|
|
2266
|
+
onlyEvaluateLocally = false;
|
|
2267
|
+
}
|
|
2268
|
+
const payloadWasLocallyEvaluated = response !== undefined;
|
|
2269
|
+
if (!payloadWasLocallyEvaluated && !onlyEvaluateLocally) {
|
|
2270
|
+
response = await super.getFeatureFlagPayloadStateless(key, distinctId, groups, personProperties, groupProperties, disableGeoip);
|
|
2271
|
+
}
|
|
2272
|
+
return response;
|
|
2297
2273
|
}
|
|
2298
2274
|
async isFeatureEnabled(key, distinctId, options) {
|
|
2299
2275
|
const feat = await this.getFeatureFlag(key, distinctId, options);
|