posthog-js-lite 3.0.2 → 3.2.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/lib/index.esm.js CHANGED
@@ -5,6 +5,8 @@ var PostHogPersistedProperty;
5
5
  PostHogPersistedProperty["Props"] = "props";
6
6
  PostHogPersistedProperty["FeatureFlags"] = "feature_flags";
7
7
  PostHogPersistedProperty["FeatureFlagPayloads"] = "feature_flag_payloads";
8
+ PostHogPersistedProperty["BootstrapFeatureFlags"] = "bootstrap_feature_flags";
9
+ PostHogPersistedProperty["BootstrapFeatureFlagPayloads"] = "bootstrap_feature_flag_payloads";
8
10
  PostHogPersistedProperty["OverrideFeatureFlags"] = "override_feature_flags";
9
11
  PostHogPersistedProperty["Queue"] = "queue";
10
12
  PostHogPersistedProperty["OptedOut"] = "opted_out";
@@ -14,6 +16,8 @@ var PostHogPersistedProperty;
14
16
  PostHogPersistedProperty["GroupProperties"] = "group_properties";
15
17
  PostHogPersistedProperty["InstalledAppBuild"] = "installed_app_build";
16
18
  PostHogPersistedProperty["InstalledAppVersion"] = "installed_app_version";
19
+ PostHogPersistedProperty["SessionReplay"] = "session_replay";
20
+ PostHogPersistedProperty["DecideEndpointWasHit"] = "decide_endpoint_was_hit";
17
21
  })(PostHogPersistedProperty || (PostHogPersistedProperty = {}));
18
22
 
19
23
  function assert(truthyValue, message) {
@@ -944,6 +948,7 @@ class PostHogCoreStateless {
944
948
  constructor(apiKey, options) {
945
949
  this.flushPromise = null;
946
950
  this.disableGeoip = true;
951
+ this.historicalMigration = false;
947
952
  this.disabled = false;
948
953
  this.defaultOptIn = true;
949
954
  this.pendingPromises = {};
@@ -957,7 +962,7 @@ class PostHogCoreStateless {
957
962
  this.maxBatchSize = Math.max(this.flushAt, options?.maxBatchSize ?? 100);
958
963
  this.maxQueueSize = Math.max(this.flushAt, options?.maxQueueSize ?? 1000);
959
964
  this.flushInterval = options?.flushInterval ?? 10000;
960
- this.captureMode = options?.captureMode || 'form';
965
+ this.captureMode = options?.captureMode || 'json';
961
966
  // If enable is explicitly set to false we override the optout
962
967
  this.defaultOptIn = options?.defaultOptIn ?? true;
963
968
  this._retryOptions = {
@@ -969,15 +974,19 @@ class PostHogCoreStateless {
969
974
  this.featureFlagsRequestTimeoutMs = options?.featureFlagsRequestTimeoutMs ?? 3000; // 3 seconds
970
975
  this.disableGeoip = options?.disableGeoip ?? true;
971
976
  this.disabled = options?.disabled ?? false;
977
+ this.historicalMigration = options?.historicalMigration ?? false;
972
978
  // Init promise allows the derived class to block calls until it is ready
973
979
  this._initPromise = Promise.resolve();
974
980
  this._isInitialized = true;
975
981
  }
982
+ logMsgIfDebug(fn) {
983
+ if (this.isDebug) {
984
+ fn();
985
+ }
986
+ }
976
987
  wrap(fn) {
977
988
  if (this.disabled) {
978
- if (this.isDebug) {
979
- console.warn('[PostHog] The client is disabled');
980
- }
989
+ this.logMsgIfDebug(() => console.warn('[PostHog] The client is disabled'));
981
990
  return;
982
991
  }
983
992
  if (this._isInitialized) {
@@ -1021,6 +1030,9 @@ class PostHogCoreStateless {
1021
1030
  get isDebug() {
1022
1031
  return !!this.removeDebugCallback;
1023
1032
  }
1033
+ get isDisabled() {
1034
+ return this.disabled;
1035
+ }
1024
1036
  buildPayload(payload) {
1025
1037
  return {
1026
1038
  distinct_id: payload.distinct_id,
@@ -1047,7 +1059,7 @@ class PostHogCoreStateless {
1047
1059
  identifyStateless(distinctId, properties, options) {
1048
1060
  this.wrap(() => {
1049
1061
  // The properties passed to identifyStateless are event properties.
1050
- // To add person properties, pass in all person properties to the `$set` key.
1062
+ // To add person properties, pass in all person properties to the `$set` and `$set_once` keys.
1051
1063
  const payload = {
1052
1064
  ...this.buildPayload({
1053
1065
  distinct_id: distinctId,
@@ -1217,7 +1229,7 @@ class PostHogCoreStateless {
1217
1229
  const queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
1218
1230
  if (queue.length >= this.maxQueueSize) {
1219
1231
  queue.shift();
1220
- console.info('Queue is full, the oldest event is dropped.');
1232
+ this.logMsgIfDebug(() => console.info('Queue is full, the oldest event is dropped.'));
1221
1233
  }
1222
1234
  queue.push({ message });
1223
1235
  this.setPersistedProperty(PostHogPersistedProperty.Queue, queue);
@@ -1283,6 +1295,9 @@ class PostHogCoreStateless {
1283
1295
  batch: messages,
1284
1296
  sent_at: currentISOTime(),
1285
1297
  };
1298
+ if (this.historicalMigration) {
1299
+ data.historical_migration = true;
1300
+ }
1286
1301
  const payload = JSON.stringify(data);
1287
1302
  const url = this.captureMode === 'form'
1288
1303
  ? `${this.host}/e/?ip=1&_=${currentTimestamp()}&v=${this.getLibraryVersion()}`
@@ -1346,33 +1361,45 @@ class PostHogCoreStateless {
1346
1361
  }, { ...this._retryOptions, ...retryOptions });
1347
1362
  }
1348
1363
  async shutdown(shutdownTimeoutMs = 30000) {
1364
+ // A little tricky - we want to have a max shutdown time and enforce it, even if that means we have some
1365
+ // dangling promises. We'll keep track of the timeout and resolve/reject based on that.
1349
1366
  await this._initPromise;
1367
+ let hasTimedOut = false;
1350
1368
  this.clearFlushTimer();
1351
- try {
1352
- await Promise.all(Object.values(this.pendingPromises));
1353
- const startTimeWithDelay = Date.now() + shutdownTimeoutMs;
1354
- while (true) {
1355
- const queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
1356
- if (queue.length === 0) {
1357
- break;
1358
- }
1359
- // flush again to make sure we send all events, some of which might've been added
1360
- // while we were waiting for the pending promises to resolve
1361
- // For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
1362
- await this.flush();
1363
- // If we've been waiting for more than the shutdownTimeoutMs, stop it
1364
- const now = Date.now();
1365
- if (startTimeWithDelay < now) {
1366
- break;
1369
+ const doShutdown = async () => {
1370
+ try {
1371
+ await Promise.all(Object.values(this.pendingPromises));
1372
+ while (true) {
1373
+ const queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
1374
+ if (queue.length === 0) {
1375
+ break;
1376
+ }
1377
+ // flush again to make sure we send all events, some of which might've been added
1378
+ // while we were waiting for the pending promises to resolve
1379
+ // For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
1380
+ await this.flush();
1381
+ if (hasTimedOut) {
1382
+ break;
1383
+ }
1367
1384
  }
1368
1385
  }
1369
- }
1370
- catch (e) {
1371
- if (!isPostHogFetchError(e)) {
1372
- throw e;
1386
+ catch (e) {
1387
+ if (!isPostHogFetchError(e)) {
1388
+ throw e;
1389
+ }
1390
+ this.logMsgIfDebug(() => console.error('Error while shutting down PostHog', e));
1373
1391
  }
1374
- console.error('Error while shutting down PostHog', e);
1375
- }
1392
+ };
1393
+ return Promise.race([
1394
+ new Promise((_, reject) => {
1395
+ safeSetTimeout(() => {
1396
+ this.logMsgIfDebug(() => console.error('Timed out while shutting down PostHog'));
1397
+ hasTimedOut = true;
1398
+ reject('Timeout while shutting down PostHog. Some events may not have been sent.');
1399
+ }, shutdownTimeoutMs);
1400
+ }),
1401
+ doShutdown(),
1402
+ ]);
1376
1403
  }
1377
1404
  }
1378
1405
  class PostHogCore extends PostHogCoreStateless {
@@ -1388,20 +1415,44 @@ class PostHogCore extends PostHogCoreStateless {
1388
1415
  this._sessionExpirationTimeSeconds = options?.sessionExpirationTimeSeconds ?? 1800; // 30 minutes
1389
1416
  }
1390
1417
  setupBootstrap(options) {
1391
- if (options?.bootstrap?.distinctId) {
1392
- if (options?.bootstrap?.isIdentifiedId) {
1393
- this.setPersistedProperty(PostHogPersistedProperty.DistinctId, options.bootstrap.distinctId);
1418
+ const bootstrap = options?.bootstrap;
1419
+ if (!bootstrap) {
1420
+ return;
1421
+ }
1422
+ // bootstrap options are only set if no persisted values are found
1423
+ // this is to prevent overwriting existing values
1424
+ if (bootstrap.distinctId) {
1425
+ if (bootstrap.isIdentifiedId) {
1426
+ const distinctId = this.getPersistedProperty(PostHogPersistedProperty.DistinctId);
1427
+ if (!distinctId) {
1428
+ this.setPersistedProperty(PostHogPersistedProperty.DistinctId, bootstrap.distinctId);
1429
+ }
1394
1430
  }
1395
1431
  else {
1396
- this.setPersistedProperty(PostHogPersistedProperty.AnonymousId, options.bootstrap.distinctId);
1432
+ const anonymousId = this.getPersistedProperty(PostHogPersistedProperty.AnonymousId);
1433
+ if (!anonymousId) {
1434
+ this.setPersistedProperty(PostHogPersistedProperty.AnonymousId, bootstrap.distinctId);
1435
+ }
1397
1436
  }
1398
1437
  }
1399
- if (options?.bootstrap?.featureFlags) {
1400
- const activeFlags = Object.keys(options.bootstrap?.featureFlags || {})
1401
- .filter((flag) => !!options.bootstrap?.featureFlags?.[flag])
1402
- .reduce((res, key) => ((res[key] = options.bootstrap?.featureFlags?.[key] || false), res), {});
1403
- this.setKnownFeatureFlags(activeFlags);
1404
- options?.bootstrap.featureFlagPayloads && this.setKnownFeatureFlagPayloads(options?.bootstrap.featureFlagPayloads);
1438
+ const bootstrapfeatureFlags = bootstrap.featureFlags;
1439
+ if (bootstrapfeatureFlags && Object.keys(bootstrapfeatureFlags).length) {
1440
+ const bootstrapFlags = Object.keys(bootstrapfeatureFlags)
1441
+ .filter((flag) => !!bootstrapfeatureFlags[flag])
1442
+ .reduce((res, key) => ((res[key] = bootstrapfeatureFlags[key] || false), res), {});
1443
+ if (Object.keys(bootstrapFlags).length) {
1444
+ this.setPersistedProperty(PostHogPersistedProperty.BootstrapFeatureFlags, bootstrapFlags);
1445
+ const currentFlags = this.getPersistedProperty(PostHogPersistedProperty.FeatureFlags) || {};
1446
+ const newFeatureFlags = { ...bootstrapFlags, ...currentFlags };
1447
+ this.setKnownFeatureFlags(newFeatureFlags);
1448
+ }
1449
+ const bootstrapFlagPayloads = bootstrap.featureFlagPayloads;
1450
+ if (bootstrapFlagPayloads && Object.keys(bootstrapFlagPayloads).length) {
1451
+ this.setPersistedProperty(PostHogPersistedProperty.BootstrapFeatureFlagPayloads, bootstrapFlagPayloads);
1452
+ const currentFlagPayloads = this.getPersistedProperty(PostHogPersistedProperty.FeatureFlagPayloads) || {};
1453
+ const newFeatureFlagPayloads = { ...bootstrapFlagPayloads, ...currentFlagPayloads };
1454
+ this.setKnownFeatureFlagPayloads(newFeatureFlagPayloads);
1455
+ }
1405
1456
  }
1406
1457
  }
1407
1458
  // NOTE: Props are lazy loaded from localstorage hence the complex getter setter logic
@@ -1417,6 +1468,7 @@ class PostHogCore extends PostHogCoreStateless {
1417
1468
  clearProps() {
1418
1469
  this.props = undefined;
1419
1470
  this.sessionProps = {};
1471
+ this.flagCallReported = {};
1420
1472
  }
1421
1473
  on(event, cb) {
1422
1474
  return this._events.on(event, cb);
@@ -1475,6 +1527,7 @@ class PostHogCore extends PostHogCoreStateless {
1475
1527
  resetSessionId() {
1476
1528
  this.wrap(() => {
1477
1529
  this.setPersistedProperty(PostHogPersistedProperty.SessionId, null);
1530
+ this.setPersistedProperty(PostHogPersistedProperty.SessionLastTimestamp, null);
1478
1531
  });
1479
1532
  }
1480
1533
  /**
@@ -1534,10 +1587,15 @@ class PostHogCore extends PostHogCoreStateless {
1534
1587
  if (properties?.$groups) {
1535
1588
  this.groups(properties.$groups);
1536
1589
  }
1590
+ // promote $set and $set_once to top level
1591
+ const userPropsOnce = properties?.$set_once;
1592
+ delete properties?.$set_once;
1593
+ // if no $set is provided we assume all properties are $set
1594
+ const userProps = properties?.$set || properties;
1537
1595
  const allProperties = this.enrichProperties({
1538
- ...properties,
1539
1596
  $anon_distinct_id: this.getAnonymousId(),
1540
- $set: properties,
1597
+ $set: userProps,
1598
+ $set_once: userPropsOnce,
1541
1599
  });
1542
1600
  if (distinctId !== previousDistinctId) {
1543
1601
  // We keep the AnonymousId to be used by decide calls and identify to link the previousId
@@ -1691,6 +1749,10 @@ class PostHogCore extends PostHogCoreStateless {
1691
1749
  };
1692
1750
  return super.getDecide(distinctId, groups, personProperties, groupProperties, extraProperties).then((res) => {
1693
1751
  if (res?.featureFlags) {
1752
+ // clear flag call reported if we have new flags since they might have changed
1753
+ if (this.sendFeatureFlagEvent) {
1754
+ this.flagCallReported = {};
1755
+ }
1694
1756
  let newFeatureFlags = res.featureFlags;
1695
1757
  let newFeatureFlagPayloads = res.featureFlagPayloads;
1696
1758
  if (res.errorsWhileComputingFlags) {
@@ -1702,6 +1764,17 @@ class PostHogCore extends PostHogCoreStateless {
1702
1764
  }
1703
1765
  this.setKnownFeatureFlags(newFeatureFlags);
1704
1766
  this.setKnownFeatureFlagPayloads(Object.fromEntries(Object.entries(newFeatureFlagPayloads || {}).map(([k, v]) => [k, this._parsePayload(v)])));
1767
+ // Mark that we hit the /decide endpoint so we can capture this in the $feature_flag_called event
1768
+ this.setPersistedProperty(PostHogPersistedProperty.DecideEndpointWasHit, true);
1769
+ const sessionReplay = res?.sessionRecording;
1770
+ if (sessionReplay) {
1771
+ this.setPersistedProperty(PostHogPersistedProperty.SessionReplay, sessionReplay);
1772
+ this.logMsgIfDebug(() => console.log('PostHog Debug', 'Session replay config: ', JSON.stringify(sessionReplay)));
1773
+ }
1774
+ else {
1775
+ this.logMsgIfDebug(() => console.info('PostHog Debug', 'Session replay config disabled.'));
1776
+ this.setPersistedProperty(PostHogPersistedProperty.SessionReplay, null);
1777
+ }
1705
1778
  }
1706
1779
  return res;
1707
1780
  });
@@ -1739,6 +1812,10 @@ class PostHogCore extends PostHogCoreStateless {
1739
1812
  this.capture('$feature_flag_called', {
1740
1813
  $feature_flag: key,
1741
1814
  $feature_flag_response: response,
1815
+ $feature_flag_bootstrapped_response: this.getPersistedProperty(PostHogPersistedProperty.BootstrapFeatureFlags)?.[key],
1816
+ $feature_flag_bootstrapped_payload: this.getPersistedProperty(PostHogPersistedProperty.BootstrapFeatureFlagPayloads)?.[key],
1817
+ // If we haven't yet received a response from the /decide endpoint, we must have used the bootstrapped value
1818
+ $used_bootstrap_value: !this.getPersistedProperty(PostHogPersistedProperty.DecideEndpointWasHit),
1742
1819
  });
1743
1820
  }
1744
1821
  // If we have flags we either return the value (true or string) or false
@@ -1803,7 +1880,7 @@ class PostHogCore extends PostHogCoreStateless {
1803
1880
  .catch((e) => {
1804
1881
  cb?.(e, undefined);
1805
1882
  if (!cb) {
1806
- console.log('[PostHog] Error reloading feature flags', e);
1883
+ this.logMsgIfDebug(() => console.log('[PostHog] Error reloading feature flags', e));
1807
1884
  }
1808
1885
  });
1809
1886
  }
@@ -1836,14 +1913,14 @@ class PostHogCore extends PostHogCoreStateless {
1836
1913
  }
1837
1914
  }
1838
1915
 
1839
- var version = "3.0.2";
1916
+ var version = "3.2.0";
1840
1917
 
1841
1918
  function getContext(window) {
1842
1919
  let context = {};
1843
-
1844
1920
  if (window.navigator) {
1845
1921
  const userAgent = window.navigator.userAgent;
1846
- context = { ...context,
1922
+ context = {
1923
+ ...context,
1847
1924
  $os: os(window),
1848
1925
  $browser: browser(userAgent, window.navigator.vendor, !!window.opera),
1849
1926
  $referrer: window.document.referrer,
@@ -1858,29 +1935,24 @@ function getContext(window) {
1858
1935
  $screen_dpr: window.devicePixelRatio
1859
1936
  };
1860
1937
  }
1861
-
1862
- context = { ...context,
1938
+ context = {
1939
+ ...context,
1863
1940
  $lib: 'js',
1864
1941
  $lib_version: version,
1865
1942
  $insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),
1866
1943
  $time: currentTimestamp() / 1000 // epoch time in seconds
1867
-
1868
1944
  };
1869
1945
  return context; // TODO: strip empty props?
1870
1946
  }
1871
-
1872
1947
  function includes(haystack, needle) {
1873
1948
  return haystack.indexOf(needle) >= 0;
1874
1949
  }
1875
-
1876
1950
  function browser(userAgent, vendor, opera) {
1877
1951
  vendor = vendor || ''; // vendor is undefined for at least IE9
1878
-
1879
1952
  if (opera || includes(userAgent, ' OPR/')) {
1880
1953
  if (includes(userAgent, 'Mini')) {
1881
1954
  return 'Opera Mini';
1882
1955
  }
1883
-
1884
1956
  return 'Opera';
1885
1957
  } else if (/(BlackBerry|PlayBook|BB10)/i.test(userAgent)) {
1886
1958
  return 'BlackBerry';
@@ -1905,7 +1977,6 @@ function browser(userAgent, vendor, opera) {
1905
1977
  if (includes(userAgent, 'Mobile')) {
1906
1978
  return 'Mobile Safari';
1907
1979
  }
1908
-
1909
1980
  return 'Safari';
1910
1981
  } else if (includes(userAgent, 'Android')) {
1911
1982
  return 'Android Mobile';
@@ -1921,7 +1992,6 @@ function browser(userAgent, vendor, opera) {
1921
1992
  return '';
1922
1993
  }
1923
1994
  }
1924
-
1925
1995
  function browserVersion(userAgent, vendor, opera) {
1926
1996
  const regexList = {
1927
1997
  'Internet Explorer Mobile': /rv:(\d+(\.\d+)?)/,
@@ -1943,28 +2013,21 @@ function browserVersion(userAgent, vendor, opera) {
1943
2013
  };
1944
2014
  const browserString = browser(userAgent, vendor, opera);
1945
2015
  const regex = regexList[browserString] || undefined;
1946
-
1947
2016
  if (regex === undefined) {
1948
2017
  return null;
1949
2018
  }
1950
-
1951
2019
  const matches = userAgent.match(regex);
1952
-
1953
2020
  if (!matches) {
1954
2021
  return null;
1955
2022
  }
1956
-
1957
2023
  return parseFloat(matches[matches.length - 2]);
1958
2024
  }
1959
-
1960
2025
  function os(window) {
1961
2026
  const a = window.navigator.userAgent;
1962
-
1963
2027
  if (/Windows/i.test(a)) {
1964
2028
  if (/Phone/.test(a) || /WPDesktop/.test(a)) {
1965
2029
  return 'Windows Phone';
1966
2030
  }
1967
-
1968
2031
  return 'Windows';
1969
2032
  } else if (/(iPhone|iPad|iPod)/.test(a)) {
1970
2033
  return 'iOS';
@@ -1982,7 +2045,6 @@ function os(window) {
1982
2045
  return '';
1983
2046
  }
1984
2047
  }
1985
-
1986
2048
  function device(userAgent) {
1987
2049
  if (/Windows Phone/i.test(userAgent) || /WPDesktop/.test(userAgent)) {
1988
2050
  return 'Windows Phone';
@@ -2000,14 +2062,11 @@ function device(userAgent) {
2000
2062
  return '';
2001
2063
  }
2002
2064
  }
2003
-
2004
2065
  function referringDomain(referrer) {
2005
2066
  const split = referrer.split('/');
2006
-
2007
2067
  if (split.length >= 3) {
2008
2068
  return split[2];
2009
2069
  }
2010
-
2011
2070
  return '';
2012
2071
  }
2013
2072
 
@@ -2017,35 +2076,29 @@ const cookieStore = {
2017
2076
  try {
2018
2077
  const nameEQ = key + '=';
2019
2078
  const ca = document.cookie.split(';');
2020
-
2021
2079
  for (let i = 0; i < ca.length; i++) {
2022
2080
  let c = ca[i];
2023
-
2024
2081
  while (c.charAt(0) == ' ') {
2025
2082
  c = c.substring(1, c.length);
2026
2083
  }
2027
-
2028
2084
  if (c.indexOf(nameEQ) === 0) {
2029
2085
  return decodeURIComponent(c.substring(nameEQ.length, c.length));
2030
2086
  }
2031
2087
  }
2032
2088
  } catch (err) {}
2033
-
2034
2089
  return null;
2035
2090
  },
2036
-
2037
2091
  setItem(key, value) {
2038
2092
  try {
2039
2093
  const cdomain = '',
2040
- expires = '',
2041
- secure = '';
2094
+ expires = '',
2095
+ secure = '';
2042
2096
  const new_cookie_val = key + '=' + encodeURIComponent(value) + expires + '; path=/' + cdomain + secure;
2043
2097
  document.cookie = new_cookie_val;
2044
2098
  } catch (err) {
2045
2099
  return;
2046
2100
  }
2047
2101
  },
2048
-
2049
2102
  removeItem(name) {
2050
2103
  try {
2051
2104
  cookieStore.setItem(name, '');
@@ -2053,147 +2106,110 @@ const cookieStore = {
2053
2106
  return;
2054
2107
  }
2055
2108
  },
2056
-
2057
2109
  clear() {
2058
2110
  document.cookie = '';
2059
2111
  },
2060
-
2061
2112
  getAllKeys() {
2062
2113
  const ca = document.cookie.split(';');
2063
2114
  const keys = [];
2064
-
2065
2115
  for (let i = 0; i < ca.length; i++) {
2066
2116
  let c = ca[i];
2067
-
2068
2117
  while (c.charAt(0) == ' ') {
2069
2118
  c = c.substring(1, c.length);
2070
2119
  }
2071
-
2072
2120
  keys.push(c.split('=')[0]);
2073
2121
  }
2074
-
2075
2122
  return keys;
2076
2123
  }
2077
-
2078
2124
  };
2079
-
2080
2125
  const createStorageLike = store => {
2081
2126
  return {
2082
2127
  getItem(key) {
2083
2128
  return store.getItem(key);
2084
2129
  },
2085
-
2086
2130
  setItem(key, value) {
2087
2131
  store.setItem(key, value);
2088
2132
  },
2089
-
2090
2133
  removeItem(key) {
2091
2134
  store.removeItem(key);
2092
2135
  },
2093
-
2094
2136
  clear() {
2095
2137
  store.clear();
2096
2138
  },
2097
-
2098
2139
  getAllKeys() {
2099
2140
  const keys = [];
2100
-
2101
2141
  for (const key in localStorage) {
2102
2142
  keys.push(key);
2103
2143
  }
2104
-
2105
2144
  return keys;
2106
2145
  }
2107
-
2108
2146
  };
2109
2147
  };
2110
-
2111
2148
  const checkStoreIsSupported = (storage, key = '__mplssupport__') => {
2112
2149
  if (!window) {
2113
2150
  return false;
2114
2151
  }
2115
-
2116
2152
  try {
2117
2153
  const val = 'xyz';
2118
2154
  storage.setItem(key, val);
2119
-
2120
2155
  if (storage.getItem(key) !== val) {
2121
2156
  return false;
2122
2157
  }
2123
-
2124
2158
  storage.removeItem(key);
2125
2159
  return true;
2126
2160
  } catch (err) {
2127
2161
  return false;
2128
2162
  }
2129
2163
  };
2130
-
2131
2164
  let localStore = undefined;
2132
2165
  let sessionStore = undefined;
2133
-
2134
2166
  const createMemoryStorage = () => {
2135
2167
  const _cache = {};
2136
2168
  const store = {
2137
2169
  getItem(key) {
2138
2170
  return _cache[key];
2139
2171
  },
2140
-
2141
2172
  setItem(key, value) {
2142
2173
  _cache[key] = value !== null ? value : undefined;
2143
2174
  },
2144
-
2145
2175
  removeItem(key) {
2146
2176
  delete _cache[key];
2147
2177
  },
2148
-
2149
2178
  clear() {
2150
2179
  for (const key in _cache) {
2151
2180
  delete _cache[key];
2152
2181
  }
2153
2182
  },
2154
-
2155
2183
  getAllKeys() {
2156
2184
  const keys = [];
2157
-
2158
2185
  for (const key in _cache) {
2159
2186
  keys.push(key);
2160
2187
  }
2161
-
2162
2188
  return keys;
2163
2189
  }
2164
-
2165
2190
  };
2166
2191
  return store;
2167
2192
  };
2168
-
2169
2193
  const getStorage = (type, window) => {
2170
2194
  if (window) {
2171
2195
  if (!localStore) {
2172
2196
  const _localStore = createStorageLike(window.localStorage);
2173
-
2174
2197
  localStore = checkStoreIsSupported(_localStore) ? _localStore : undefined;
2175
2198
  }
2176
-
2177
2199
  if (!sessionStore) {
2178
2200
  const _sessionStore = createStorageLike(window.sessionStorage);
2179
-
2180
2201
  sessionStore = checkStoreIsSupported(_sessionStore) ? _sessionStore : undefined;
2181
2202
  }
2182
2203
  }
2183
-
2184
2204
  switch (type) {
2185
2205
  case 'cookie':
2186
2206
  return cookieStore || localStore || sessionStore || createMemoryStorage();
2187
-
2188
2207
  case 'localStorage':
2189
2208
  return localStore || sessionStore || createMemoryStorage();
2190
-
2191
2209
  case 'sessionStorage':
2192
2210
  return sessionStore || createMemoryStorage();
2193
-
2194
2211
  case 'memory':
2195
2212
  return createMemoryStorage();
2196
-
2197
2213
  default:
2198
2214
  return createMemoryStorage();
2199
2215
  }
@@ -2201,61 +2217,50 @@ const getStorage = (type, window) => {
2201
2217
 
2202
2218
  class PostHog extends PostHogCore {
2203
2219
  constructor(apiKey, options) {
2204
- super(apiKey, options); // posthog-js stores options in one object on
2205
-
2220
+ super(apiKey, options);
2221
+ // posthog-js stores options in one object on
2206
2222
  this._storageKey = options?.persistence_name ? `ph_${options.persistence_name}` : `ph_${apiKey}_posthog`;
2207
2223
  this._storage = getStorage(options?.persistence || 'localStorage', window);
2208
2224
  this.setupBootstrap(options);
2209
-
2210
2225
  if (options?.preloadFeatureFlags !== false) {
2211
2226
  this.reloadFeatureFlags();
2212
2227
  }
2213
2228
  }
2214
-
2215
2229
  getPersistedProperty(key) {
2216
2230
  if (!this._storageCache) {
2217
2231
  this._storageCache = JSON.parse(this._storage.getItem(this._storageKey) || '{}') || {};
2218
2232
  }
2219
-
2220
2233
  return this._storageCache[key];
2221
2234
  }
2222
-
2223
2235
  setPersistedProperty(key, value) {
2224
2236
  if (!this._storageCache) {
2225
2237
  this._storageCache = JSON.parse(this._storage.getItem(this._storageKey) || '{}') || {};
2226
2238
  }
2227
-
2228
2239
  if (value === null) {
2229
2240
  delete this._storageCache[key];
2230
2241
  } else {
2231
2242
  this._storageCache[key] = value;
2232
2243
  }
2233
-
2234
2244
  this._storage.setItem(this._storageKey, JSON.stringify(this._storageCache));
2235
2245
  }
2236
-
2237
2246
  fetch(url, options) {
2238
2247
  return window.fetch(url, options);
2239
2248
  }
2240
-
2241
2249
  getLibraryId() {
2242
2250
  return 'posthog-js-lite';
2243
2251
  }
2244
-
2245
2252
  getLibraryVersion() {
2246
2253
  return version;
2247
2254
  }
2248
-
2249
2255
  getCustomUserAgent() {
2250
2256
  return;
2251
2257
  }
2252
-
2253
2258
  getCommonEventProperties() {
2254
- return { ...super.getCommonEventProperties(),
2259
+ return {
2260
+ ...super.getCommonEventProperties(),
2255
2261
  ...getContext(window)
2256
2262
  };
2257
2263
  }
2258
-
2259
2264
  }
2260
2265
 
2261
2266
  export { PostHog, PostHog as default };