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