posthog-js-lite 4.0.0 → 4.1.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 +4 -0
- package/lib/index.cjs +59 -171
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +27 -25
- package/lib/index.mjs +59 -171
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/posthog-web.spec.ts +1 -1
package/CHANGELOG.md
CHANGED
package/lib/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var version = "4.
|
|
5
|
+
var version = "4.1.0";
|
|
6
6
|
|
|
7
7
|
var PostHogPersistedProperty;
|
|
8
8
|
(function (PostHogPersistedProperty) {
|
|
@@ -26,11 +26,11 @@ var PostHogPersistedProperty;
|
|
|
26
26
|
PostHogPersistedProperty["InstalledAppBuild"] = "installed_app_build";
|
|
27
27
|
PostHogPersistedProperty["InstalledAppVersion"] = "installed_app_version";
|
|
28
28
|
PostHogPersistedProperty["SessionReplay"] = "session_replay";
|
|
29
|
-
PostHogPersistedProperty["DecideEndpointWasHit"] = "decide_endpoint_was_hit";
|
|
30
29
|
PostHogPersistedProperty["SurveyLastSeenDate"] = "survey_last_seen_date";
|
|
31
30
|
PostHogPersistedProperty["SurveysSeen"] = "surveys_seen";
|
|
32
31
|
PostHogPersistedProperty["Surveys"] = "surveys";
|
|
33
32
|
PostHogPersistedProperty["RemoteConfig"] = "remote_config";
|
|
33
|
+
PostHogPersistedProperty["FlagsEndpointWasHit"] = "flags_endpoint_was_hit";
|
|
34
34
|
})(PostHogPersistedProperty || (PostHogPersistedProperty = {}));
|
|
35
35
|
// Any key prefixed with `attr__` can be added
|
|
36
36
|
var Compression;
|
|
@@ -98,27 +98,27 @@ var ActionStepStringMatching;
|
|
|
98
98
|
ActionStepStringMatching["Regex"] = "regex";
|
|
99
99
|
})(ActionStepStringMatching || (ActionStepStringMatching = {}));
|
|
100
100
|
|
|
101
|
-
const
|
|
102
|
-
if ('flags' in
|
|
103
|
-
// Convert
|
|
104
|
-
const featureFlags = getFlagValuesFromFlags(
|
|
105
|
-
const featureFlagPayloads = getPayloadsFromFlags(
|
|
101
|
+
const normalizeFlagsResponse = (flagsResponse) => {
|
|
102
|
+
if ('flags' in flagsResponse) {
|
|
103
|
+
// Convert v2 format to v1 format
|
|
104
|
+
const featureFlags = getFlagValuesFromFlags(flagsResponse.flags);
|
|
105
|
+
const featureFlagPayloads = getPayloadsFromFlags(flagsResponse.flags);
|
|
106
106
|
return {
|
|
107
|
-
...
|
|
107
|
+
...flagsResponse,
|
|
108
108
|
featureFlags,
|
|
109
109
|
featureFlagPayloads,
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
else {
|
|
113
|
-
// Convert
|
|
114
|
-
const featureFlags =
|
|
115
|
-
const featureFlagPayloads = Object.fromEntries(Object.entries(
|
|
113
|
+
// Convert v1 format to v2 format
|
|
114
|
+
const featureFlags = flagsResponse.featureFlags ?? {};
|
|
115
|
+
const featureFlagPayloads = Object.fromEntries(Object.entries(flagsResponse.featureFlagPayloads || {}).map(([k, v]) => [k, parsePayload(v)]));
|
|
116
116
|
const flags = Object.fromEntries(Object.entries(featureFlags).map(([key, value]) => [
|
|
117
117
|
key,
|
|
118
118
|
getFlagDetailFromFlagAndPayload(key, value, featureFlagPayloads[key]),
|
|
119
119
|
]));
|
|
120
120
|
return {
|
|
121
|
-
...
|
|
121
|
+
...flagsResponse,
|
|
122
122
|
featureFlags,
|
|
123
123
|
featureFlagPayloads,
|
|
124
124
|
flags,
|
|
@@ -190,7 +190,7 @@ const parsePayload = (response) => {
|
|
|
190
190
|
* @param featureFlagPayloads - The feature flag payloads
|
|
191
191
|
* @returns The normalized flag details
|
|
192
192
|
*/
|
|
193
|
-
const
|
|
193
|
+
const createFlagsResponseFromFlagsAndPayloads = (featureFlags, featureFlagPayloads) => {
|
|
194
194
|
// If a feature flag payload key is not in the feature flags, we treat it as true feature flag.
|
|
195
195
|
const allKeys = [...new Set([...Object.keys(featureFlags ?? {}), ...Object.keys(featureFlagPayloads ?? {})])];
|
|
196
196
|
const enabledFlags = allKeys
|
|
@@ -200,7 +200,7 @@ const createDecideResponseFromFlagsAndPayloads = (featureFlags, featureFlagPaylo
|
|
|
200
200
|
featureFlags: enabledFlags,
|
|
201
201
|
featureFlagPayloads: featureFlagPayloads ?? {},
|
|
202
202
|
};
|
|
203
|
-
return
|
|
203
|
+
return normalizeFlagsResponse(flagDetails);
|
|
204
204
|
};
|
|
205
205
|
const updateFlagValue = (flag, value) => {
|
|
206
206
|
return {
|
|
@@ -216,90 +216,6 @@ function getVariantFromValue(value) {
|
|
|
216
216
|
return typeof value === 'string' ? value : undefined;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
// Rollout constants
|
|
220
|
-
const NEW_FLAGS_ROLLOUT_PERCENTAGE = 1;
|
|
221
|
-
// The fnv1a hashes of the tokens that are explicitly excluded from the rollout
|
|
222
|
-
// see https://github.com/PostHog/posthog-js-lite/blob/main/posthog-core/src/utils.ts#L84
|
|
223
|
-
// are hashed API tokens from our top 10 for each category supported by this SDK.
|
|
224
|
-
const NEW_FLAGS_EXCLUDED_HASHES = new Set([
|
|
225
|
-
// Node
|
|
226
|
-
'61be3dd8',
|
|
227
|
-
'96f6df5f',
|
|
228
|
-
'8cfdba9b',
|
|
229
|
-
'bf027177',
|
|
230
|
-
'e59430a8',
|
|
231
|
-
'7fa5500b',
|
|
232
|
-
'569798e9',
|
|
233
|
-
'04809ff7',
|
|
234
|
-
'0ebc61a5',
|
|
235
|
-
'32de7f98',
|
|
236
|
-
'3beeb69a',
|
|
237
|
-
'12d34ad9',
|
|
238
|
-
'733853ec',
|
|
239
|
-
'0645bb64',
|
|
240
|
-
'5dcbee21',
|
|
241
|
-
'b1f95fa3',
|
|
242
|
-
'2189e408',
|
|
243
|
-
'82b460c2',
|
|
244
|
-
'3a8cc979',
|
|
245
|
-
'29ef8843',
|
|
246
|
-
'2cdbf767',
|
|
247
|
-
'38084b54',
|
|
248
|
-
// React Native
|
|
249
|
-
'50f9f8de',
|
|
250
|
-
'41d0df91',
|
|
251
|
-
'5c236689',
|
|
252
|
-
'c11aedd3',
|
|
253
|
-
'ada46672',
|
|
254
|
-
'f4331ee1',
|
|
255
|
-
'42fed62a',
|
|
256
|
-
'c957462c',
|
|
257
|
-
'd62f705a',
|
|
258
|
-
// Web (lots of teams per org, hence lots of API tokens)
|
|
259
|
-
'e0162666',
|
|
260
|
-
'01b3e5cf',
|
|
261
|
-
'441cef7f',
|
|
262
|
-
'bb9cafee',
|
|
263
|
-
'8f348eb0',
|
|
264
|
-
'b2553f3a',
|
|
265
|
-
'97469d7d',
|
|
266
|
-
'39f21a76',
|
|
267
|
-
'03706dcc',
|
|
268
|
-
'27d50569',
|
|
269
|
-
'307584a7',
|
|
270
|
-
'6433e92e',
|
|
271
|
-
'150c7fbb',
|
|
272
|
-
'49f57f22',
|
|
273
|
-
'3772f65b',
|
|
274
|
-
'01eb8256',
|
|
275
|
-
'3c9e9234',
|
|
276
|
-
'f853c7f7',
|
|
277
|
-
'c0ac4b67',
|
|
278
|
-
'cd609d40',
|
|
279
|
-
'10ca9b1a',
|
|
280
|
-
'8a87f11b',
|
|
281
|
-
'8e8e5216',
|
|
282
|
-
'1f6b63b3',
|
|
283
|
-
'db7943dd',
|
|
284
|
-
'79b7164c',
|
|
285
|
-
'07f78e33',
|
|
286
|
-
'2d21b6fd',
|
|
287
|
-
'952db5ee',
|
|
288
|
-
'a7d3b43f',
|
|
289
|
-
'1924dd9c',
|
|
290
|
-
'84e1b8f6',
|
|
291
|
-
'dff631b6',
|
|
292
|
-
'c5aa8a79',
|
|
293
|
-
'fa133a95',
|
|
294
|
-
'498a4508',
|
|
295
|
-
'24748755',
|
|
296
|
-
'98f3d658',
|
|
297
|
-
'21bbda67',
|
|
298
|
-
'7dbfed69',
|
|
299
|
-
'be3ec24c',
|
|
300
|
-
'fc80b8e2',
|
|
301
|
-
'75cc0998',
|
|
302
|
-
]);
|
|
303
219
|
const STRING_FORMAT = 'utf8';
|
|
304
220
|
function assert(truthyValue, message) {
|
|
305
221
|
if (!truthyValue || typeof truthyValue !== 'string' || isEmpty(truthyValue)) {
|
|
@@ -355,30 +271,6 @@ const isError = (x) => {
|
|
|
355
271
|
function getFetch() {
|
|
356
272
|
return typeof fetch !== 'undefined' ? fetch : typeof globalThis.fetch !== 'undefined' ? globalThis.fetch : undefined;
|
|
357
273
|
}
|
|
358
|
-
// FNV-1a hash function
|
|
359
|
-
// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
|
360
|
-
// I know, I know, I'm rolling my own hash function, but I didn't want to take on
|
|
361
|
-
// a crypto dependency and this is just temporary anyway
|
|
362
|
-
function fnv1a(str) {
|
|
363
|
-
let hash = 0x811c9dc5; // FNV offset basis
|
|
364
|
-
for (let i = 0; i < str.length; i++) {
|
|
365
|
-
hash ^= str.charCodeAt(i);
|
|
366
|
-
hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
|
367
|
-
}
|
|
368
|
-
// Convert to hex string, padding to 8 chars
|
|
369
|
-
return (hash >>> 0).toString(16).padStart(8, '0');
|
|
370
|
-
}
|
|
371
|
-
function isTokenInRollout(token, percentage = 0, excludedHashes) {
|
|
372
|
-
const tokenHash = fnv1a(token);
|
|
373
|
-
// Check excluded hashes (we're explicitly including these tokens from the rollout)
|
|
374
|
-
if (excludedHashes?.has(tokenHash)) {
|
|
375
|
-
return false;
|
|
376
|
-
}
|
|
377
|
-
// Convert hash to int and divide by max value to get number between 0-1
|
|
378
|
-
const hashInt = parseInt(tokenHash, 16);
|
|
379
|
-
const hashFloat = hashInt / 0xffffffff;
|
|
380
|
-
return hashFloat < percentage;
|
|
381
|
-
}
|
|
382
274
|
function allSettled(promises) {
|
|
383
275
|
return Promise.all(promises.map((p) => (p ?? Promise.resolve()).then((value) => ({ status: 'fulfilled', value }), (reason) => ({ status: 'rejected', reason }))));
|
|
384
276
|
}
|
|
@@ -1110,13 +1002,9 @@ class PostHogCoreStateless {
|
|
|
1110
1002
|
/***
|
|
1111
1003
|
*** FEATURE FLAGS
|
|
1112
1004
|
***/
|
|
1113
|
-
async
|
|
1005
|
+
async getFlags(distinctId, groups = {}, personProperties = {}, groupProperties = {}, extraPayload = {}) {
|
|
1114
1006
|
await this._initPromise;
|
|
1115
|
-
|
|
1116
|
-
// This is a temporary measure to ensure that we can still use the old flags API
|
|
1117
|
-
// while we migrate to the new flags API
|
|
1118
|
-
const useFlags = isTokenInRollout(this.apiKey, NEW_FLAGS_ROLLOUT_PERCENTAGE, NEW_FLAGS_EXCLUDED_HASHES);
|
|
1119
|
-
const url = useFlags ? `${this.host}/flags/?v=2` : `${this.host}/decide/?v=4`;
|
|
1007
|
+
const url = `${this.host}/flags/?v=2&config=true`;
|
|
1120
1008
|
const fetchOptions = {
|
|
1121
1009
|
method: 'POST',
|
|
1122
1010
|
headers: { ...this.getCustomHeaders(), 'Content-Type': 'application/json' },
|
|
@@ -1129,11 +1017,11 @@ class PostHogCoreStateless {
|
|
|
1129
1017
|
...extraPayload,
|
|
1130
1018
|
}),
|
|
1131
1019
|
};
|
|
1132
|
-
this.logMsgIfDebug(() => console.log('PostHog Debug', '
|
|
1133
|
-
// Don't retry /
|
|
1020
|
+
this.logMsgIfDebug(() => console.log('PostHog Debug', 'Flags URL', url));
|
|
1021
|
+
// Don't retry /flags API calls
|
|
1134
1022
|
return this.fetchWithRetry(url, fetchOptions, { retryCount: 0 }, this.featureFlagsRequestTimeoutMs)
|
|
1135
1023
|
.then((response) => response.json())
|
|
1136
|
-
.then((response) =>
|
|
1024
|
+
.then((response) => normalizeFlagsResponse(response))
|
|
1137
1025
|
.catch((error) => {
|
|
1138
1026
|
this._events.emit('error', error);
|
|
1139
1027
|
return undefined;
|
|
@@ -1162,15 +1050,15 @@ class PostHogCoreStateless {
|
|
|
1162
1050
|
}
|
|
1163
1051
|
async getFeatureFlagDetailStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1164
1052
|
await this._initPromise;
|
|
1165
|
-
const
|
|
1166
|
-
if (
|
|
1053
|
+
const flagsResponse = await this.getFeatureFlagDetailsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip, [key]);
|
|
1054
|
+
if (flagsResponse === undefined) {
|
|
1167
1055
|
return undefined;
|
|
1168
1056
|
}
|
|
1169
|
-
const featureFlags =
|
|
1057
|
+
const featureFlags = flagsResponse.flags;
|
|
1170
1058
|
const flagDetail = featureFlags[key];
|
|
1171
1059
|
return {
|
|
1172
1060
|
response: flagDetail,
|
|
1173
|
-
requestId:
|
|
1061
|
+
requestId: flagsResponse.requestId,
|
|
1174
1062
|
};
|
|
1175
1063
|
}
|
|
1176
1064
|
async getFeatureFlagPayloadStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
@@ -1220,26 +1108,26 @@ class PostHogCoreStateless {
|
|
|
1220
1108
|
if (flagKeysToEvaluate) {
|
|
1221
1109
|
extraPayload['flag_keys_to_evaluate'] = flagKeysToEvaluate;
|
|
1222
1110
|
}
|
|
1223
|
-
const
|
|
1224
|
-
if (
|
|
1111
|
+
const flagsResponse = await this.getFlags(distinctId, groups, personProperties, groupProperties, extraPayload);
|
|
1112
|
+
if (flagsResponse === undefined) {
|
|
1225
1113
|
// We probably errored out, so return undefined
|
|
1226
1114
|
return undefined;
|
|
1227
1115
|
}
|
|
1228
|
-
// if there's an error on the
|
|
1229
|
-
if (
|
|
1116
|
+
// if there's an error on the flagsResponse, log a console error, but don't throw an error
|
|
1117
|
+
if (flagsResponse.errorsWhileComputingFlags) {
|
|
1230
1118
|
console.error('[FEATURE FLAGS] Error while computing feature flags, some flags may be missing or incorrect. Learn more at https://posthog.com/docs/feature-flags/best-practices');
|
|
1231
1119
|
}
|
|
1232
1120
|
// Add check for quota limitation on feature flags
|
|
1233
|
-
if (
|
|
1121
|
+
if (flagsResponse.quotaLimited?.includes(QuotaLimitedFeature.FeatureFlags)) {
|
|
1234
1122
|
console.warn('[FEATURE FLAGS] Feature flags quota limit exceeded - feature flags unavailable. Learn more about billing limits at https://posthog.com/docs/billing/limits-alerts');
|
|
1235
1123
|
return {
|
|
1236
1124
|
flags: {},
|
|
1237
1125
|
featureFlags: {},
|
|
1238
1126
|
featureFlagPayloads: {},
|
|
1239
|
-
requestId:
|
|
1127
|
+
requestId: flagsResponse?.requestId,
|
|
1240
1128
|
};
|
|
1241
1129
|
}
|
|
1242
|
-
return
|
|
1130
|
+
return flagsResponse;
|
|
1243
1131
|
}
|
|
1244
1132
|
/***
|
|
1245
1133
|
*** SURVEYS
|
|
@@ -1671,7 +1559,7 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
1671
1559
|
const bootstrapFeatureFlags = bootstrap.featureFlags;
|
|
1672
1560
|
const bootstrapFeatureFlagPayloads = bootstrap.featureFlagPayloads ?? {};
|
|
1673
1561
|
if (bootstrapFeatureFlags && Object.keys(bootstrapFeatureFlags).length) {
|
|
1674
|
-
const normalizedBootstrapFeatureFlagDetails =
|
|
1562
|
+
const normalizedBootstrapFeatureFlagDetails = createFlagsResponseFromFlagsAndPayloads(bootstrapFeatureFlags, bootstrapFeatureFlagPayloads);
|
|
1675
1563
|
if (Object.keys(normalizedBootstrapFeatureFlagDetails.flags).length > 0) {
|
|
1676
1564
|
this.setBootstrappedFeatureFlagDetails(normalizedBootstrapFeatureFlagDetails);
|
|
1677
1565
|
const currentFeatureFlagDetails = this.getKnownFeatureFlagDetails() || { flags: {}, requestId: undefined };
|
|
@@ -1813,7 +1701,7 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
1813
1701
|
...maybeAdd('$set_once', userPropsOnce),
|
|
1814
1702
|
});
|
|
1815
1703
|
if (distinctId !== previousDistinctId) {
|
|
1816
|
-
// We keep the AnonymousId to be used by
|
|
1704
|
+
// We keep the AnonymousId to be used by flags calls and identify to link the previousId
|
|
1817
1705
|
this.setPersistedProperty(PostHogPersistedProperty.AnonymousId, previousDistinctId);
|
|
1818
1706
|
this.setPersistedProperty(PostHogPersistedProperty.DistinctId, distinctId);
|
|
1819
1707
|
this.reloadFeatureFlags();
|
|
@@ -1941,12 +1829,12 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
1941
1829
|
/***
|
|
1942
1830
|
*** FEATURE FLAGS
|
|
1943
1831
|
***/
|
|
1944
|
-
async
|
|
1832
|
+
async flagsAsync(sendAnonDistinctId = true) {
|
|
1945
1833
|
await this._initPromise;
|
|
1946
|
-
if (this.
|
|
1947
|
-
return this.
|
|
1834
|
+
if (this._flagsResponsePromise) {
|
|
1835
|
+
return this._flagsResponsePromise;
|
|
1948
1836
|
}
|
|
1949
|
-
return this.
|
|
1837
|
+
return this._flagsAsync(sendAnonDistinctId);
|
|
1950
1838
|
}
|
|
1951
1839
|
cacheSessionReplay(source, response) {
|
|
1952
1840
|
const sessionReplay = response?.sessionRecording;
|
|
@@ -2017,8 +1905,8 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
2017
1905
|
});
|
|
2018
1906
|
return this._remoteConfigResponsePromise;
|
|
2019
1907
|
}
|
|
2020
|
-
async
|
|
2021
|
-
this.
|
|
1908
|
+
async _flagsAsync(sendAnonDistinctId = true) {
|
|
1909
|
+
this._flagsResponsePromise = this._initPromise
|
|
2022
1910
|
.then(async () => {
|
|
2023
1911
|
const distinctId = this.getDistinctId();
|
|
2024
1912
|
const groups = this.props.$groups || {};
|
|
@@ -2028,7 +1916,7 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
2028
1916
|
const extraProperties = {
|
|
2029
1917
|
$anon_distinct_id: sendAnonDistinctId ? this.getAnonymousId() : undefined,
|
|
2030
1918
|
};
|
|
2031
|
-
const res = await super.
|
|
1919
|
+
const res = await super.getFlags(distinctId, groups, personProperties, groupProperties, extraProperties);
|
|
2032
1920
|
// Add check for quota limitation on feature flags
|
|
2033
1921
|
if (res?.quotaLimited?.includes(QuotaLimitedFeature.FeatureFlags)) {
|
|
2034
1922
|
// Unset all feature flags by setting to null
|
|
@@ -2052,22 +1940,22 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
2052
1940
|
};
|
|
2053
1941
|
}
|
|
2054
1942
|
this.setKnownFeatureFlagDetails(newFeatureFlagDetails);
|
|
2055
|
-
// Mark that we hit the /
|
|
2056
|
-
this.setPersistedProperty(PostHogPersistedProperty.
|
|
2057
|
-
this.cacheSessionReplay('
|
|
1943
|
+
// Mark that we hit the /flags endpoint so we can capture this in the $feature_flag_called event
|
|
1944
|
+
this.setPersistedProperty(PostHogPersistedProperty.FlagsEndpointWasHit, true);
|
|
1945
|
+
this.cacheSessionReplay('flags', res);
|
|
2058
1946
|
}
|
|
2059
1947
|
return res;
|
|
2060
1948
|
})
|
|
2061
1949
|
.finally(() => {
|
|
2062
|
-
this.
|
|
1950
|
+
this._flagsResponsePromise = undefined;
|
|
2063
1951
|
});
|
|
2064
|
-
return this.
|
|
1952
|
+
return this._flagsResponsePromise;
|
|
2065
1953
|
}
|
|
2066
1954
|
// We only store the flags and request id in the feature flag details storage key
|
|
2067
|
-
setKnownFeatureFlagDetails(
|
|
1955
|
+
setKnownFeatureFlagDetails(flagsResponse) {
|
|
2068
1956
|
this.wrap(() => {
|
|
2069
|
-
this.setPersistedProperty(PostHogPersistedProperty.FeatureFlagDetails,
|
|
2070
|
-
this._events.emit('featureflags', getFlagValuesFromFlags(
|
|
1957
|
+
this.setPersistedProperty(PostHogPersistedProperty.FeatureFlagDetails, flagsResponse);
|
|
1958
|
+
this._events.emit('featureflags', getFlagValuesFromFlags(flagsResponse?.flags ?? {}));
|
|
2071
1959
|
});
|
|
2072
1960
|
}
|
|
2073
1961
|
getKnownFeatureFlagDetails() {
|
|
@@ -2079,9 +1967,9 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
2079
1967
|
if (featureFlags === undefined && featureFlagPayloads === undefined) {
|
|
2080
1968
|
return undefined;
|
|
2081
1969
|
}
|
|
2082
|
-
return
|
|
1970
|
+
return createFlagsResponseFromFlagsAndPayloads(featureFlags ?? {}, featureFlagPayloads ?? {});
|
|
2083
1971
|
}
|
|
2084
|
-
return
|
|
1972
|
+
return normalizeFlagsResponse(storedDetails);
|
|
2085
1973
|
}
|
|
2086
1974
|
getKnownFeatureFlags() {
|
|
2087
1975
|
const featureFlagDetails = this.getKnownFeatureFlagDetails();
|
|
@@ -2145,8 +2033,8 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
2145
2033
|
...maybeAdd('$feature_flag_reason', featureFlag?.reason?.description ?? featureFlag?.reason?.code),
|
|
2146
2034
|
...maybeAdd('$feature_flag_bootstrapped_response', bootstrappedResponse),
|
|
2147
2035
|
...maybeAdd('$feature_flag_bootstrapped_payload', bootstrappedPayload),
|
|
2148
|
-
// If we haven't yet received a response from the /
|
|
2149
|
-
$used_bootstrap_value: !this.getPersistedProperty(PostHogPersistedProperty.
|
|
2036
|
+
// If we haven't yet received a response from the /flags endpoint, we must have used the bootstrapped value
|
|
2037
|
+
$used_bootstrap_value: !this.getPersistedProperty(PostHogPersistedProperty.FlagsEndpointWasHit),
|
|
2150
2038
|
...maybeAdd('$feature_flag_request_id', details.requestId),
|
|
2151
2039
|
});
|
|
2152
2040
|
}
|
|
@@ -2195,7 +2083,7 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
2195
2083
|
...details,
|
|
2196
2084
|
flags,
|
|
2197
2085
|
};
|
|
2198
|
-
return
|
|
2086
|
+
return normalizeFlagsResponse(result);
|
|
2199
2087
|
}
|
|
2200
2088
|
getFeatureFlagsAndPayloads() {
|
|
2201
2089
|
const flags = this.getFeatureFlags();
|
|
@@ -2213,14 +2101,14 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
2213
2101
|
return !!response;
|
|
2214
2102
|
}
|
|
2215
2103
|
// Used when we want to trigger the reload but we don't care about the result
|
|
2216
|
-
reloadFeatureFlags(
|
|
2217
|
-
this.
|
|
2104
|
+
reloadFeatureFlags(options) {
|
|
2105
|
+
this.flagsAsync(true)
|
|
2218
2106
|
.then((res) => {
|
|
2219
|
-
cb?.(undefined, res?.featureFlags);
|
|
2107
|
+
options?.cb?.(undefined, res?.featureFlags);
|
|
2220
2108
|
})
|
|
2221
2109
|
.catch((e) => {
|
|
2222
|
-
cb?.(e, undefined);
|
|
2223
|
-
if (!cb) {
|
|
2110
|
+
options?.cb?.(e, undefined);
|
|
2111
|
+
if (!options?.cb) {
|
|
2224
2112
|
this.logMsgIfDebug(() => console.log('PostHog Debug', 'Error reloading feature flags', e));
|
|
2225
2113
|
}
|
|
2226
2114
|
});
|
|
@@ -2228,8 +2116,8 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
2228
2116
|
async reloadRemoteConfigAsync() {
|
|
2229
2117
|
return await this.remoteConfigAsync();
|
|
2230
2118
|
}
|
|
2231
|
-
async reloadFeatureFlagsAsync(sendAnonDistinctId
|
|
2232
|
-
return (await this.
|
|
2119
|
+
async reloadFeatureFlagsAsync(sendAnonDistinctId) {
|
|
2120
|
+
return (await this.flagsAsync(sendAnonDistinctId ?? true))?.featureFlags;
|
|
2233
2121
|
}
|
|
2234
2122
|
onFeatureFlags(cb) {
|
|
2235
2123
|
return this.on('featureflags', async () => {
|