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 +6 -0
- package/lib/{index.cjs.js → index.cjs} +297 -140
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.ts +661 -642
- package/lib/{index.esm.js → index.mjs} +297 -140
- package/lib/index.mjs.map +1 -0
- package/package.json +3 -3
- package/src/context.ts +1 -1
- package/src/patch.ts +50 -0
- package/src/posthog-web.ts +6 -9
- package/src/types.ts +1 -1
- package/tsconfig.json +1 -0
- package/lib/index.cjs.js.map +0 -1
- package/lib/index.esm.js.map +0 -1
- package/lib/posthog-core/src/eventemitter.d.ts +0 -8
- package/lib/posthog-core/src/featureFlagUtils.d.ts +0 -34
- package/lib/posthog-core/src/index.d.ts +0 -239
- package/lib/posthog-core/src/lz-string.d.ts +0 -8
- package/lib/posthog-core/src/patch.d.ts +0 -3
- package/lib/posthog-core/src/types.d.ts +0 -422
- package/lib/posthog-core/src/utils.d.ts +0 -19
- package/lib/posthog-core/src/vendor/uuidv7.d.ts +0 -179
- package/lib/posthog-web/index.d.ts +0 -3
- package/lib/posthog-web/src/context.d.ts +0 -1
- package/lib/posthog-web/src/posthog-web.d.ts +0 -19
- package/lib/posthog-web/src/storage.d.ts +0 -10
- package/lib/posthog-web/src/types.d.ts +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -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
|
|
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
|
-
|
|
1678
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1836
|
+
let queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
|
|
1701
1837
|
if (!queue.length) {
|
|
1702
1838
|
return [];
|
|
1703
1839
|
}
|
|
1704
|
-
const
|
|
1705
|
-
const
|
|
1706
|
-
|
|
1707
|
-
const
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
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
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
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
|
-
|
|
1736
|
-
|
|
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
|
-
|
|
1745
|
-
|
|
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
|
-
|
|
1748
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
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.
|
|
3107
|
+
//# sourceMappingURL=index.cjs.map
|