posthog-js-lite 3.1.0 → 3.2.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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # Next
2
2
 
3
+ # 3.2.1 - 2025-01-17
4
+
5
+ ## Fixed
6
+
7
+ 1. fix: check if window and fetch are available before using on web env
8
+
9
+ # 3.2.0 - 2024-12-12
10
+
11
+ ## Changed
12
+
13
+ 1. Add new debugging property `$feature_flag_bootstrapped_response`, `$feature_flag_bootstrapped_payload` and `$used_bootstrap_value` to `$feature_flag_called` event
14
+
15
+
3
16
  # 3.1.0 - 2024-11-21
4
17
 
5
18
  ## Changed
package/lib/index.cjs.js CHANGED
@@ -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) {
@@ -62,6 +65,9 @@ function safeSetTimeout(fn, timeout) {
62
65
  // We unref if available to prevent Node.js hanging on exit
63
66
  t?.unref && t?.unref();
64
67
  return t;
68
+ }
69
+ function getFetch() {
70
+ return typeof fetch !== 'undefined' ? fetch : typeof global.fetch !== 'undefined' ? global.fetch : undefined;
65
71
  }
66
72
 
67
73
  // Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>
@@ -1442,12 +1448,14 @@ class PostHogCore extends PostHogCoreStateless {
1442
1448
  .filter((flag) => !!bootstrapfeatureFlags[flag])
1443
1449
  .reduce((res, key) => ((res[key] = bootstrapfeatureFlags[key] || false), res), {});
1444
1450
  if (Object.keys(bootstrapFlags).length) {
1451
+ this.setPersistedProperty(PostHogPersistedProperty.BootstrapFeatureFlags, bootstrapFlags);
1445
1452
  const currentFlags = this.getPersistedProperty(PostHogPersistedProperty.FeatureFlags) || {};
1446
1453
  const newFeatureFlags = { ...bootstrapFlags, ...currentFlags };
1447
1454
  this.setKnownFeatureFlags(newFeatureFlags);
1448
1455
  }
1449
1456
  const bootstrapFlagPayloads = bootstrap.featureFlagPayloads;
1450
1457
  if (bootstrapFlagPayloads && Object.keys(bootstrapFlagPayloads).length) {
1458
+ this.setPersistedProperty(PostHogPersistedProperty.BootstrapFeatureFlagPayloads, bootstrapFlagPayloads);
1451
1459
  const currentFlagPayloads = this.getPersistedProperty(PostHogPersistedProperty.FeatureFlagPayloads) || {};
1452
1460
  const newFeatureFlagPayloads = { ...bootstrapFlagPayloads, ...currentFlagPayloads };
1453
1461
  this.setKnownFeatureFlagPayloads(newFeatureFlagPayloads);
@@ -1763,6 +1771,8 @@ class PostHogCore extends PostHogCoreStateless {
1763
1771
  }
1764
1772
  this.setKnownFeatureFlags(newFeatureFlags);
1765
1773
  this.setKnownFeatureFlagPayloads(Object.fromEntries(Object.entries(newFeatureFlagPayloads || {}).map(([k, v]) => [k, this._parsePayload(v)])));
1774
+ // Mark that we hit the /decide endpoint so we can capture this in the $feature_flag_called event
1775
+ this.setPersistedProperty(PostHogPersistedProperty.DecideEndpointWasHit, true);
1766
1776
  const sessionReplay = res?.sessionRecording;
1767
1777
  if (sessionReplay) {
1768
1778
  this.setPersistedProperty(PostHogPersistedProperty.SessionReplay, sessionReplay);
@@ -1809,6 +1819,10 @@ class PostHogCore extends PostHogCoreStateless {
1809
1819
  this.capture('$feature_flag_called', {
1810
1820
  $feature_flag: key,
1811
1821
  $feature_flag_response: response,
1822
+ $feature_flag_bootstrapped_response: this.getPersistedProperty(PostHogPersistedProperty.BootstrapFeatureFlags)?.[key],
1823
+ $feature_flag_bootstrapped_payload: this.getPersistedProperty(PostHogPersistedProperty.BootstrapFeatureFlagPayloads)?.[key],
1824
+ // If we haven't yet received a response from the /decide endpoint, we must have used the bootstrapped value
1825
+ $used_bootstrap_value: !this.getPersistedProperty(PostHogPersistedProperty.DecideEndpointWasHit),
1812
1826
  });
1813
1827
  }
1814
1828
  // If we have flags we either return the value (true or string) or false
@@ -1906,15 +1920,18 @@ class PostHogCore extends PostHogCoreStateless {
1906
1920
  }
1907
1921
  }
1908
1922
 
1909
- var version = "3.1.0";
1923
+ var version = "3.2.1";
1910
1924
 
1911
1925
  function getContext(window) {
1912
1926
  let context = {};
1913
- if (window.navigator) {
1927
+ if (window?.navigator) {
1914
1928
  const userAgent = window.navigator.userAgent;
1929
+ const osValue = os(window);
1915
1930
  context = {
1916
1931
  ...context,
1917
- $os: os(window),
1932
+ ...(osValue !== undefined && {
1933
+ $os: osValue
1934
+ }),
1918
1935
  $browser: browser(userAgent, window.navigator.vendor, !!window.opera),
1919
1936
  $referrer: window.document.referrer,
1920
1937
  $referring_domain: referringDomain(window.document.referrer),
@@ -2016,6 +2033,9 @@ function browserVersion(userAgent, vendor, opera) {
2016
2033
  return parseFloat(matches[matches.length - 2]);
2017
2034
  }
2018
2035
  function os(window) {
2036
+ if (!window?.navigator) {
2037
+ return undefined;
2038
+ }
2019
2039
  const a = window.navigator.userAgent;
2020
2040
  if (/Windows/i.test(a)) {
2021
2041
  if (/Phone/.test(a) || /WPDesktop/.test(a)) {
@@ -2035,7 +2055,7 @@ function os(window) {
2035
2055
  } else if (/CrOS/.test(a)) {
2036
2056
  return 'Chrome OS';
2037
2057
  } else {
2038
- return '';
2058
+ return undefined;
2039
2059
  }
2040
2060
  }
2041
2061
  function device(userAgent) {
@@ -2139,9 +2159,6 @@ const createStorageLike = store => {
2139
2159
  };
2140
2160
  };
2141
2161
  const checkStoreIsSupported = (storage, key = '__mplssupport__') => {
2142
- if (!window) {
2143
- return false;
2144
- }
2145
2162
  try {
2146
2163
  const val = 'xyz';
2147
2164
  storage.setItem(key, val);
@@ -2213,12 +2230,15 @@ class PostHog extends PostHogCore {
2213
2230
  super(apiKey, options);
2214
2231
  // posthog-js stores options in one object on
2215
2232
  this._storageKey = options?.persistence_name ? `ph_${options.persistence_name}` : `ph_${apiKey}_posthog`;
2216
- this._storage = getStorage(options?.persistence || 'localStorage', window);
2233
+ this._storage = getStorage(options?.persistence || 'localStorage', this.getWindow());
2217
2234
  this.setupBootstrap(options);
2218
2235
  if (options?.preloadFeatureFlags !== false) {
2219
2236
  this.reloadFeatureFlags();
2220
2237
  }
2221
2238
  }
2239
+ getWindow() {
2240
+ return typeof window !== 'undefined' ? window : undefined;
2241
+ }
2222
2242
  getPersistedProperty(key) {
2223
2243
  if (!this._storageCache) {
2224
2244
  this._storageCache = JSON.parse(this._storage.getItem(this._storageKey) || '{}') || {};
@@ -2237,7 +2257,12 @@ class PostHog extends PostHogCore {
2237
2257
  this._storage.setItem(this._storageKey, JSON.stringify(this._storageCache));
2238
2258
  }
2239
2259
  fetch(url, options) {
2240
- return window.fetch(url, options);
2260
+ const fetchFn = getFetch();
2261
+ if (!fetchFn) {
2262
+ // error will be handled by the caller (fetchWithRetry)
2263
+ return Promise.reject(new Error('Fetch API is not available in this environment.'));
2264
+ }
2265
+ return fetchFn(url, options);
2241
2266
  }
2242
2267
  getLibraryId() {
2243
2268
  return 'posthog-js-lite';
@@ -2251,7 +2276,7 @@ class PostHog extends PostHogCore {
2251
2276
  getCommonEventProperties() {
2252
2277
  return {
2253
2278
  ...super.getCommonEventProperties(),
2254
- ...getContext(window)
2279
+ ...getContext(this.getWindow())
2255
2280
  };
2256
2281
  }
2257
2282
  }