posthog-js-lite 3.5.0 → 3.5.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,11 @@
1
1
  # Next
2
2
 
3
+ # 3.5.1 – 2025-05-06
4
+
5
+ ## Fixed
6
+
7
+ 1. Fix exported file extensions to work with older Node versions
8
+
3
9
  # 3.5.0 – 2025-04-17
4
10
 
5
11
  ## Added
@@ -2,6 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var version = "3.5.1";
6
+
5
7
  var PostHogPersistedProperty;
6
8
  (function (PostHogPersistedProperty) {
7
9
  PostHogPersistedProperty["AnonymousId"] = "anonymous_id";
@@ -291,6 +293,7 @@ const NEW_FLAGS_EXCLUDED_HASHES = new Set([
291
293
  'fc80b8e2',
292
294
  '75cc0998',
293
295
  ]);
296
+ const STRING_FORMAT = 'utf8';
294
297
  function assert(truthyValue, message) {
295
298
  if (!truthyValue || typeof truthyValue !== 'string' || isEmpty(truthyValue)) {
296
299
  throw new Error(message);
@@ -343,12 +346,8 @@ const isError = (x) => {
343
346
  return x instanceof Error;
344
347
  };
345
348
  function getFetch() {
346
- return typeof fetch !== 'undefined' ? fetch : typeof global.fetch !== 'undefined' ? global.fetch : undefined;
349
+ return typeof fetch !== 'undefined' ? fetch : typeof globalThis.fetch !== 'undefined' ? globalThis.fetch : undefined;
347
350
  }
348
- // copied from: https://github.com/PostHog/posthog-js/blob/main/react/src/utils/type-utils.ts#L4
349
- const isFunction = function (f) {
350
- return typeof f === 'function';
351
- };
352
351
  // FNV-1a hash function
353
352
  // https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
354
353
  // I know, I know, I'm rolling my own hash function, but I didn't want to take on
@@ -1236,11 +1235,21 @@ const uuidv7 = () => uuidv7obj().toString();
1236
1235
  const uuidv7obj = () => (defaultGenerator || (defaultGenerator = new V7Generator())).generate();
1237
1236
 
1238
1237
  class PostHogFetchHttpError extends Error {
1239
- constructor(response) {
1240
- super('HTTP error while fetching PostHog: ' + response.status);
1238
+ constructor(response, reqByteLength) {
1239
+ super('HTTP error while fetching PostHog: status=' + response.status + ', reqByteLength=' + reqByteLength);
1241
1240
  this.response = response;
1241
+ this.reqByteLength = reqByteLength;
1242
1242
  this.name = 'PostHogFetchHttpError';
1243
1243
  }
1244
+ get status() {
1245
+ return this.response.status;
1246
+ }
1247
+ get text() {
1248
+ return this.response.text();
1249
+ }
1250
+ get json() {
1251
+ return this.response.json();
1252
+ }
1244
1253
  }
1245
1254
  class PostHogFetchNetworkError extends Error {
1246
1255
  constructor(error) {
@@ -1252,9 +1261,26 @@ class PostHogFetchNetworkError extends Error {
1252
1261
  this.name = 'PostHogFetchNetworkError';
1253
1262
  }
1254
1263
  }
1264
+ async function logFlushError(err) {
1265
+ if (err instanceof PostHogFetchHttpError) {
1266
+ let text = '';
1267
+ try {
1268
+ text = await err.text;
1269
+ }
1270
+ catch { }
1271
+ console.error(`Error while flushing PostHog: message=${err.message}, response body=${text}`, err);
1272
+ }
1273
+ else {
1274
+ console.error('Error while flushing PostHog', err);
1275
+ }
1276
+ return Promise.resolve();
1277
+ }
1255
1278
  function isPostHogFetchError(err) {
1256
1279
  return typeof err === 'object' && (err instanceof PostHogFetchHttpError || err instanceof PostHogFetchNetworkError);
1257
1280
  }
1281
+ function isPostHogFetchContentTooLargeError(err) {
1282
+ return typeof err === 'object' && err instanceof PostHogFetchHttpError && err.status === 413;
1283
+ }
1258
1284
  var QuotaLimitedFeature;
1259
1285
  (function (QuotaLimitedFeature) {
1260
1286
  QuotaLimitedFeature["FeatureFlags"] = "feature_flags";
@@ -1263,6 +1289,7 @@ var QuotaLimitedFeature;
1263
1289
  class PostHogCoreStateless {
1264
1290
  constructor(apiKey, options) {
1265
1291
  this.flushPromise = null;
1292
+ this.shutdownPromise = null;
1266
1293
  this.pendingPromises = {};
1267
1294
  // internal
1268
1295
  this._events = new SimpleEventEmitter();
@@ -1385,12 +1412,26 @@ class PostHogCoreStateless {
1385
1412
  this.enqueue('identify', payload, options);
1386
1413
  });
1387
1414
  }
1415
+ async identifyStatelessImmediate(distinctId, properties, options) {
1416
+ const payload = {
1417
+ ...this.buildPayload({
1418
+ distinct_id: distinctId,
1419
+ event: '$identify',
1420
+ properties,
1421
+ }),
1422
+ };
1423
+ await this.sendImmediate('identify', payload, options);
1424
+ }
1388
1425
  captureStateless(distinctId, event, properties, options) {
1389
1426
  this.wrap(() => {
1390
1427
  const payload = this.buildPayload({ distinct_id: distinctId, event, properties });
1391
1428
  this.enqueue('capture', payload, options);
1392
1429
  });
1393
1430
  }
1431
+ async captureStatelessImmediate(distinctId, event, properties, options) {
1432
+ const payload = this.buildPayload({ distinct_id: distinctId, event, properties });
1433
+ await this.sendImmediate('capture', payload, options);
1434
+ }
1394
1435
  aliasStateless(alias, distinctId, properties, options) {
1395
1436
  this.wrap(() => {
1396
1437
  const payload = this.buildPayload({
@@ -1405,6 +1446,18 @@ class PostHogCoreStateless {
1405
1446
  this.enqueue('alias', payload, options);
1406
1447
  });
1407
1448
  }
1449
+ async aliasStatelessImmediate(alias, distinctId, properties, options) {
1450
+ const payload = this.buildPayload({
1451
+ event: '$create_alias',
1452
+ distinct_id: distinctId,
1453
+ properties: {
1454
+ ...(properties || {}),
1455
+ distinct_id: distinctId,
1456
+ alias,
1457
+ },
1458
+ });
1459
+ await this.sendImmediate('alias', payload, options);
1460
+ }
1408
1461
  /***
1409
1462
  *** GROUPS
1410
1463
  ***/
@@ -1615,6 +1668,30 @@ class PostHogCoreStateless {
1615
1668
  }
1616
1669
  return newSurveys ?? [];
1617
1670
  }
1671
+ get props() {
1672
+ if (!this._props) {
1673
+ this._props = this.getPersistedProperty(PostHogPersistedProperty.Props);
1674
+ }
1675
+ return this._props || {};
1676
+ }
1677
+ set props(val) {
1678
+ this._props = val;
1679
+ }
1680
+ async register(properties) {
1681
+ this.wrap(() => {
1682
+ this.props = {
1683
+ ...this.props,
1684
+ ...properties,
1685
+ };
1686
+ this.setPersistedProperty(PostHogPersistedProperty.Props, this.props);
1687
+ });
1688
+ }
1689
+ async unregister(property) {
1690
+ this.wrap(() => {
1691
+ delete this.props[property];
1692
+ this.setPersistedProperty(PostHogPersistedProperty.Props, this.props);
1693
+ });
1694
+ }
1618
1695
  /***
1619
1696
  *** QUEUEING AND FLUSHING
1620
1697
  ***/
@@ -1624,25 +1701,7 @@ class PostHogCoreStateless {
1624
1701
  this._events.emit(type, `Library is disabled. Not sending event. To re-enable, call posthog.optIn()`);
1625
1702
  return;
1626
1703
  }
1627
- const message = {
1628
- ..._message,
1629
- type: type,
1630
- library: this.getLibraryId(),
1631
- library_version: this.getLibraryVersion(),
1632
- timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
1633
- uuid: options?.uuid ? options.uuid : uuidv7(),
1634
- };
1635
- const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
1636
- if (addGeoipDisableProperty) {
1637
- if (!message.properties) {
1638
- message.properties = {};
1639
- }
1640
- message['properties']['$geoip_disable'] = true;
1641
- }
1642
- if (message.distinctId) {
1643
- message.distinct_id = message.distinctId;
1644
- delete message.distinctId;
1645
- }
1704
+ const message = this.prepareMessage(type, _message, options);
1646
1705
  const queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
1647
1706
  if (queue.length >= this.maxQueueSize) {
1648
1707
  queue.shift();
@@ -1660,6 +1719,73 @@ class PostHogCoreStateless {
1660
1719
  }
1661
1720
  });
1662
1721
  }
1722
+ async sendImmediate(type, _message, options) {
1723
+ if (this.disabled) {
1724
+ this.logMsgIfDebug(() => console.warn('[PostHog] The client is disabled'));
1725
+ return;
1726
+ }
1727
+ if (!this._isInitialized) {
1728
+ await this._initPromise;
1729
+ }
1730
+ if (this.optedOut) {
1731
+ this._events.emit(type, `Library is disabled. Not sending event. To re-enable, call posthog.optIn()`);
1732
+ return;
1733
+ }
1734
+ const data = {
1735
+ api_key: this.apiKey,
1736
+ batch: [this.prepareMessage(type, _message, options)],
1737
+ sent_at: currentISOTime(),
1738
+ };
1739
+ if (this.historicalMigration) {
1740
+ data.historical_migration = true;
1741
+ }
1742
+ const payload = JSON.stringify(data);
1743
+ const url = this.captureMode === 'form'
1744
+ ? `${this.host}/e/?ip=1&_=${currentTimestamp()}&v=${this.getLibraryVersion()}`
1745
+ : `${this.host}/batch/`;
1746
+ const fetchOptions = this.captureMode === 'form'
1747
+ ? {
1748
+ method: 'POST',
1749
+ mode: 'no-cors',
1750
+ credentials: 'omit',
1751
+ headers: { ...this.getCustomHeaders(), 'Content-Type': 'application/x-www-form-urlencoded' },
1752
+ body: `data=${encodeURIComponent(LZString.compressToBase64(payload))}&compression=lz64`,
1753
+ }
1754
+ : {
1755
+ method: 'POST',
1756
+ headers: { ...this.getCustomHeaders(), 'Content-Type': 'application/json' },
1757
+ body: payload,
1758
+ };
1759
+ try {
1760
+ await this.fetchWithRetry(url, fetchOptions);
1761
+ }
1762
+ catch (err) {
1763
+ this._events.emit('error', err);
1764
+ throw err;
1765
+ }
1766
+ }
1767
+ prepareMessage(type, _message, options) {
1768
+ const message = {
1769
+ ..._message,
1770
+ type: type,
1771
+ library: this.getLibraryId(),
1772
+ library_version: this.getLibraryVersion(),
1773
+ timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
1774
+ uuid: options?.uuid ? options.uuid : uuidv7(),
1775
+ };
1776
+ const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
1777
+ if (addGeoipDisableProperty) {
1778
+ if (!message.properties) {
1779
+ message.properties = {};
1780
+ }
1781
+ message['properties']['$geoip_disable'] = true;
1782
+ }
1783
+ if (message.distinctId) {
1784
+ message.distinct_id = message.distinctId;
1785
+ delete message.distinctId;
1786
+ }
1787
+ return message;
1788
+ }
1663
1789
  clearFlushTimer() {
1664
1790
  if (this._flushTimer) {
1665
1791
  clearTimeout(this._flushTimer);
@@ -1671,16 +1797,26 @@ class PostHogCoreStateless {
1671
1797
  * Avoids unnecessary promise errors
1672
1798
  */
1673
1799
  flushBackground() {
1674
- void this.flush().catch(() => { });
1800
+ void this.flush().catch(async (err) => {
1801
+ await logFlushError(err);
1802
+ });
1675
1803
  }
1676
1804
  async flush() {
1677
- if (!this.flushPromise) {
1678
- this.flushPromise = this._flush().finally(() => {
1805
+ // Wait for the current flush operation to finish (regardless of success or failure), then try to flush again.
1806
+ // Use allSettled instead of finally to be defensive around flush throwing errors immediately rather than rejecting.
1807
+ const nextFlushPromise = Promise.allSettled([this.flushPromise]).then(() => {
1808
+ return this._flush();
1809
+ });
1810
+ this.flushPromise = nextFlushPromise;
1811
+ void this.addPendingPromise(nextFlushPromise);
1812
+ Promise.allSettled([nextFlushPromise]).then(() => {
1813
+ // If there are no others waiting to flush, clear the promise.
1814
+ // We don't strictly need to do this, but it could make debugging easier
1815
+ if (this.flushPromise === nextFlushPromise) {
1679
1816
  this.flushPromise = null;
1680
- });
1681
- this.addPendingPromise(this.flushPromise);
1682
- }
1683
- return this.flushPromise;
1817
+ }
1818
+ });
1819
+ return nextFlushPromise;
1684
1820
  }
1685
1821
  getCustomHeaders() {
1686
1822
  // Don't set the user agent if we're not on a browser. The latest spec allows
@@ -1697,56 +1833,80 @@ class PostHogCoreStateless {
1697
1833
  async _flush() {
1698
1834
  this.clearFlushTimer();
1699
1835
  await this._initPromise;
1700
- const queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
1836
+ let queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
1701
1837
  if (!queue.length) {
1702
1838
  return [];
1703
1839
  }
1704
- const items = queue.slice(0, this.maxBatchSize);
1705
- const messages = items.map((item) => item.message);
1706
- const persistQueueChange = () => {
1707
- const refreshedQueue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
1708
- this.setPersistedProperty(PostHogPersistedProperty.Queue, refreshedQueue.slice(items.length));
1709
- };
1710
- const data = {
1711
- api_key: this.apiKey,
1712
- batch: messages,
1713
- sent_at: currentISOTime(),
1714
- };
1715
- if (this.historicalMigration) {
1716
- data.historical_migration = true;
1717
- }
1718
- const payload = JSON.stringify(data);
1719
- const url = this.captureMode === 'form'
1720
- ? `${this.host}/e/?ip=1&_=${currentTimestamp()}&v=${this.getLibraryVersion()}`
1721
- : `${this.host}/batch/`;
1722
- const fetchOptions = this.captureMode === 'form'
1723
- ? {
1724
- method: 'POST',
1725
- mode: 'no-cors',
1726
- credentials: 'omit',
1727
- headers: { ...this.getCustomHeaders(), 'Content-Type': 'application/x-www-form-urlencoded' },
1728
- body: `data=${encodeURIComponent(LZString.compressToBase64(payload))}&compression=lz64`,
1840
+ const sentMessages = [];
1841
+ const originalQueueLength = queue.length;
1842
+ while (queue.length > 0 && sentMessages.length < originalQueueLength) {
1843
+ const batchItems = queue.slice(0, this.maxBatchSize);
1844
+ const batchMessages = batchItems.map((item) => item.message);
1845
+ const persistQueueChange = () => {
1846
+ const refreshedQueue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
1847
+ const newQueue = refreshedQueue.slice(batchItems.length);
1848
+ this.setPersistedProperty(PostHogPersistedProperty.Queue, newQueue);
1849
+ queue = newQueue;
1850
+ };
1851
+ const data = {
1852
+ api_key: this.apiKey,
1853
+ batch: batchMessages,
1854
+ sent_at: currentISOTime(),
1855
+ };
1856
+ if (this.historicalMigration) {
1857
+ data.historical_migration = true;
1729
1858
  }
1730
- : {
1731
- method: 'POST',
1732
- headers: { ...this.getCustomHeaders(), 'Content-Type': 'application/json' },
1733
- body: payload,
1859
+ const payload = JSON.stringify(data);
1860
+ const url = this.captureMode === 'form'
1861
+ ? `${this.host}/e/?ip=1&_=${currentTimestamp()}&v=${this.getLibraryVersion()}`
1862
+ : `${this.host}/batch/`;
1863
+ const fetchOptions = this.captureMode === 'form'
1864
+ ? {
1865
+ method: 'POST',
1866
+ mode: 'no-cors',
1867
+ credentials: 'omit',
1868
+ headers: { ...this.getCustomHeaders(), 'Content-Type': 'application/x-www-form-urlencoded' },
1869
+ body: `data=${encodeURIComponent(LZString.compressToBase64(payload))}&compression=lz64`,
1870
+ }
1871
+ : {
1872
+ method: 'POST',
1873
+ headers: { ...this.getCustomHeaders(), 'Content-Type': 'application/json' },
1874
+ body: payload,
1875
+ };
1876
+ const retryOptions = {
1877
+ retryCheck: (err) => {
1878
+ // don't automatically retry on 413 errors, we want to reduce the batch size first
1879
+ if (isPostHogFetchContentTooLargeError(err)) {
1880
+ return false;
1881
+ }
1882
+ // otherwise, retry on network errors
1883
+ return isPostHogFetchError(err);
1884
+ },
1734
1885
  };
1735
- try {
1736
- await this.fetchWithRetry(url, fetchOptions);
1737
- }
1738
- catch (err) {
1739
- // depending on the error type, eg a malformed JSON or broken queue, it'll always return an error
1740
- // and this will be an endless loop, in this case, if the error isn't a network issue, we always remove the items from the queue
1741
- if (!(err instanceof PostHogFetchNetworkError)) {
1742
- persistQueueChange();
1886
+ try {
1887
+ await this.fetchWithRetry(url, fetchOptions, retryOptions);
1743
1888
  }
1744
- this._events.emit('error', err);
1745
- throw err;
1889
+ catch (err) {
1890
+ if (isPostHogFetchContentTooLargeError(err) && batchMessages.length > 1) {
1891
+ // if we get a 413 error, we want to reduce the batch size and try again
1892
+ this.maxBatchSize = Math.max(1, Math.floor(batchMessages.length / 2));
1893
+ this.logMsgIfDebug(() => console.warn(`Received 413 when sending batch of size ${batchMessages.length}, reducing batch size to ${this.maxBatchSize}`));
1894
+ // do not persist the queue change, we want to retry the same batch
1895
+ continue;
1896
+ }
1897
+ // depending on the error type, eg a malformed JSON or broken queue, it'll always return an error
1898
+ // and this will be an endless loop, in this case, if the error isn't a network issue, we always remove the items from the queue
1899
+ if (!(err instanceof PostHogFetchNetworkError)) {
1900
+ persistQueueChange();
1901
+ }
1902
+ this._events.emit('error', err);
1903
+ throw err;
1904
+ }
1905
+ persistQueueChange();
1906
+ sentMessages.push(...batchMessages);
1746
1907
  }
1747
- persistQueueChange();
1748
- this._events.emit('flush', messages);
1749
- return messages;
1908
+ this._events.emit('flush', sentMessages);
1909
+ return sentMessages;
1750
1910
  }
1751
1911
  async fetchWithRetry(url, options, retryOptions, requestTimeout) {
1752
1912
  var _a;
@@ -1755,6 +1915,8 @@ class PostHogCoreStateless {
1755
1915
  setTimeout(() => ctrl.abort(), ms);
1756
1916
  return ctrl.signal;
1757
1917
  });
1918
+ const body = options.body ? options.body : '';
1919
+ const reqByteLength = Buffer.byteLength(body, STRING_FORMAT);
1758
1920
  return await retriable(async () => {
1759
1921
  let res = null;
1760
1922
  try {
@@ -1772,12 +1934,12 @@ class PostHogCoreStateless {
1772
1934
  // https://developer.mozilla.org/en-US/docs/Web/API/Request/mode#no-cors
1773
1935
  const isNoCors = options.mode === 'no-cors';
1774
1936
  if (!isNoCors && (res.status < 200 || res.status >= 400)) {
1775
- throw new PostHogFetchHttpError(res);
1937
+ throw new PostHogFetchHttpError(res, reqByteLength);
1776
1938
  }
1777
1939
  return res;
1778
1940
  }, { ...this._retryOptions, ...retryOptions });
1779
1941
  }
1780
- async shutdown(shutdownTimeoutMs = 30000) {
1942
+ async _shutdown(shutdownTimeoutMs = 30000) {
1781
1943
  // A little tricky - we want to have a max shutdown time and enforce it, even if that means we have some
1782
1944
  // dangling promises. We'll keep track of the timeout and resolve/reject based on that.
1783
1945
  await this._initPromise;
@@ -1804,7 +1966,7 @@ class PostHogCoreStateless {
1804
1966
  if (!isPostHogFetchError(e)) {
1805
1967
  throw e;
1806
1968
  }
1807
- this.logMsgIfDebug(() => console.error('Error while shutting down PostHog', e));
1969
+ await logFlushError(e);
1808
1970
  }
1809
1971
  };
1810
1972
  return Promise.race([
@@ -1818,6 +1980,22 @@ class PostHogCoreStateless {
1818
1980
  doShutdown(),
1819
1981
  ]);
1820
1982
  }
1983
+ /**
1984
+ * Call shutdown() once before the node process exits, so ensure that all events have been sent and all promises
1985
+ * have resolved. Do not use this function if you intend to keep using this PostHog instance after calling it.
1986
+ * @param shutdownTimeoutMs
1987
+ */
1988
+ async shutdown(shutdownTimeoutMs = 30000) {
1989
+ if (this.shutdownPromise) {
1990
+ this.logMsgIfDebug(() => console.warn('shutdown() called while already shutting down. shutdown() is meant to be called once before process exit - use flush() for per-request cleanup'));
1991
+ }
1992
+ else {
1993
+ this.shutdownPromise = this._shutdown(shutdownTimeoutMs).finally(() => {
1994
+ this.shutdownPromise = null;
1995
+ });
1996
+ }
1997
+ return this.shutdownPromise;
1998
+ }
1821
1999
  }
1822
2000
  class PostHogCore extends PostHogCoreStateless {
1823
2001
  constructor(apiKey, options) {
@@ -1870,16 +2048,6 @@ class PostHogCore extends PostHogCoreStateless {
1870
2048
  }
1871
2049
  }
1872
2050
  }
1873
- // NOTE: Props are lazy loaded from localstorage hence the complex getter setter logic
1874
- get props() {
1875
- if (!this._props) {
1876
- this._props = this.getPersistedProperty(PostHogPersistedProperty.Props);
1877
- }
1878
- return this._props || {};
1879
- }
1880
- set props(val) {
1881
- this._props = val;
1882
- }
1883
2051
  clearProps() {
1884
2052
  this.props = undefined;
1885
2053
  this.sessionProps = {};
@@ -1969,21 +2137,6 @@ class PostHogCore extends PostHogCoreStateless {
1969
2137
  }
1970
2138
  return this.getPersistedProperty(PostHogPersistedProperty.DistinctId) || this.getAnonymousId();
1971
2139
  }
1972
- async unregister(property) {
1973
- this.wrap(() => {
1974
- delete this.props[property];
1975
- this.setPersistedProperty(PostHogPersistedProperty.Props, this.props);
1976
- });
1977
- }
1978
- async register(properties) {
1979
- this.wrap(() => {
1980
- this.props = {
1981
- ...this.props,
1982
- ...properties,
1983
- };
1984
- this.setPersistedProperty(PostHogPersistedProperty.Props, this.props);
1985
- });
1986
- }
1987
2140
  registerForSession(properties) {
1988
2141
  this.sessionProps = {
1989
2142
  ...this.sessionProps,
@@ -2503,8 +2656,6 @@ class PostHogCore extends PostHogCoreStateless {
2503
2656
  }
2504
2657
  }
2505
2658
 
2506
- var version = "3.5.0";
2507
-
2508
2659
  function getContext(window) {
2509
2660
  let context = {};
2510
2661
  if (window?.navigator) {
@@ -2808,39 +2959,45 @@ const getStorage = (type, window) => {
2808
2959
  }
2809
2960
  };
2810
2961
 
2811
- // import { patch } from 'rrweb/typings/utils'
2812
- function patch(source, name, replacement) {
2813
- try {
2814
- if (!(name in source)) {
2815
- return () => {
2816
- //
2817
- };
2818
- }
2819
- const original = source[name];
2820
- const wrapped = replacement(original);
2821
- // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work
2822
- // otherwise it'll throw "TypeError: Object.defineProperties called on non-object"
2823
- if (isFunction(wrapped)) {
2824
- wrapped.prototype = wrapped.prototype || {};
2825
- Object.defineProperties(wrapped, {
2826
- __posthog_wrapped__: {
2827
- enumerable: false,
2828
- value: true,
2829
- },
2830
- });
2831
- }
2832
- source[name] = wrapped;
2833
- return () => {
2834
- source[name] = original;
2835
- };
2836
- }
2837
- catch {
2838
- return () => {
2839
- //
2840
- };
2841
- // This can throw if multiple fill happens on a global object like XMLHttpRequest
2842
- // Fixes https://github.com/getsentry/sentry-javascript/issues/2043
2843
- }
2962
+ // import { patch } from 'rrweb/typings/utils'
2963
+ // copied from: https://github.com/PostHog/posthog-js/blob/main/src/extensions/replay/rrweb-plugins/patch.ts
2964
+ // which was copied from https://github.com/rrweb-io/rrweb/blob/8aea5b00a4dfe5a6f59bd2ae72bb624f45e51e81/packages/rrweb/src/utils.ts#L129
2965
+ // which was copied from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts
2966
+ // copied from: https://github.com/PostHog/posthog-js/blob/main/react/src/utils/type-utils.ts#L4
2967
+ const isFunction = function (f) {
2968
+ return typeof f === 'function';
2969
+ };
2970
+ function patch(source, name, replacement) {
2971
+ try {
2972
+ if (!(name in source)) {
2973
+ return () => {
2974
+ //
2975
+ };
2976
+ }
2977
+ const original = source[name];
2978
+ const wrapped = replacement(original);
2979
+ // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work
2980
+ // otherwise it'll throw "TypeError: Object.defineProperties called on non-object"
2981
+ if (isFunction(wrapped)) {
2982
+ wrapped.prototype = wrapped.prototype || {};
2983
+ Object.defineProperties(wrapped, {
2984
+ __posthog_wrapped__: {
2985
+ enumerable: false,
2986
+ value: true
2987
+ }
2988
+ });
2989
+ }
2990
+ source[name] = wrapped;
2991
+ return () => {
2992
+ source[name] = original;
2993
+ };
2994
+ } catch {
2995
+ return () => {
2996
+ //
2997
+ };
2998
+ // This can throw if multiple fill happens on a global object like XMLHttpRequest
2999
+ // Fixes https://github.com/getsentry/sentry-javascript/issues/2043
3000
+ }
2844
3001
  }
2845
3002
 
2846
3003
  class PostHog extends PostHogCore {
@@ -2947,4 +3104,4 @@ class PostHog extends PostHogCore {
2947
3104
 
2948
3105
  exports.PostHog = PostHog;
2949
3106
  exports["default"] = PostHog;
2950
- //# sourceMappingURL=index.cjs.js.map
3107
+ //# sourceMappingURL=index.cjs.map