posthog-node 4.17.1 → 4.18.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/CHANGELOG.md +11 -0
- package/lib/edge/index.cjs +94 -11
- package/lib/edge/index.cjs.map +1 -1
- package/lib/edge/index.mjs +94 -11
- package/lib/edge/index.mjs.map +1 -1
- package/lib/index.d.ts +70 -57
- package/lib/node/index.cjs +94 -11
- package/lib/node/index.cjs.map +1 -1
- package/lib/node/index.mjs +94 -11
- package/lib/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/lib/edge/index.cjs
CHANGED
|
@@ -589,6 +589,47 @@ function addUnhandledRejectionListener(captureFn) {
|
|
|
589
589
|
});
|
|
590
590
|
}
|
|
591
591
|
|
|
592
|
+
// Portions of this file are derived from getsentry/sentry-javascript by Software, Inc. dba Sentry
|
|
593
|
+
// Licensed under the MIT License
|
|
594
|
+
let parsedStackResults;
|
|
595
|
+
let lastKeysCount;
|
|
596
|
+
let cachedFilenameChunkIds;
|
|
597
|
+
function getFilenameToChunkIdMap(stackParser) {
|
|
598
|
+
const chunkIdMap = globalThis._posthogChunkIds;
|
|
599
|
+
if (!chunkIdMap) {
|
|
600
|
+
console.error('No chunk id map found');
|
|
601
|
+
return {};
|
|
602
|
+
}
|
|
603
|
+
const chunkIdKeys = Object.keys(chunkIdMap);
|
|
604
|
+
if (cachedFilenameChunkIds && chunkIdKeys.length === lastKeysCount) {
|
|
605
|
+
return cachedFilenameChunkIds;
|
|
606
|
+
}
|
|
607
|
+
lastKeysCount = chunkIdKeys.length;
|
|
608
|
+
cachedFilenameChunkIds = chunkIdKeys.reduce((acc, stackKey) => {
|
|
609
|
+
if (!parsedStackResults) {
|
|
610
|
+
parsedStackResults = {};
|
|
611
|
+
}
|
|
612
|
+
const result = parsedStackResults[stackKey];
|
|
613
|
+
if (result) {
|
|
614
|
+
acc[result[0]] = result[1];
|
|
615
|
+
} else {
|
|
616
|
+
const parsedStack = stackParser(stackKey);
|
|
617
|
+
for (let i = parsedStack.length - 1; i >= 0; i--) {
|
|
618
|
+
const stackFrame = parsedStack[i];
|
|
619
|
+
const filename = stackFrame?.filename;
|
|
620
|
+
const chunkId = chunkIdMap[stackKey];
|
|
621
|
+
if (filename && chunkId) {
|
|
622
|
+
acc[filename] = chunkId;
|
|
623
|
+
parsedStackResults[stackKey] = [filename, chunkId];
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return acc;
|
|
629
|
+
}, {});
|
|
630
|
+
return cachedFilenameChunkIds;
|
|
631
|
+
}
|
|
632
|
+
|
|
592
633
|
// Portions of this file are derived from getsentry/sentry-javascript by Software, Inc. dba Sentry
|
|
593
634
|
// Licensed under the MIT License
|
|
594
635
|
function isEvent(candidate) {
|
|
@@ -822,7 +863,16 @@ async function exceptionFromError(stackParser, frameModifiers, error) {
|
|
|
822
863
|
* Extracts stack frames from the error.stack string
|
|
823
864
|
*/
|
|
824
865
|
function parseStackFrames(stackParser, error) {
|
|
825
|
-
return stackParser(error.stack || '', 1);
|
|
866
|
+
return applyChunkIds(stackParser(error.stack || '', 1), stackParser);
|
|
867
|
+
}
|
|
868
|
+
function applyChunkIds(frames, parser) {
|
|
869
|
+
const filenameChunkIdMap = getFilenameToChunkIdMap(parser);
|
|
870
|
+
frames.forEach(frame => {
|
|
871
|
+
if (frame.filename) {
|
|
872
|
+
frame.chunk_id = filenameChunkIdMap[frame.filename];
|
|
873
|
+
}
|
|
874
|
+
});
|
|
875
|
+
return frames;
|
|
826
876
|
}
|
|
827
877
|
|
|
828
878
|
const SHUTDOWN_TIMEOUT = 2000;
|
|
@@ -885,7 +935,7 @@ function setupExpressErrorHandler(_posthog, app) {
|
|
|
885
935
|
});
|
|
886
936
|
}
|
|
887
937
|
|
|
888
|
-
var version = "4.
|
|
938
|
+
var version = "4.18.0";
|
|
889
939
|
|
|
890
940
|
var PostHogPersistedProperty;
|
|
891
941
|
(function (PostHogPersistedProperty) {
|
|
@@ -902,6 +952,7 @@ var PostHogPersistedProperty;
|
|
|
902
952
|
PostHogPersistedProperty["Queue"] = "queue";
|
|
903
953
|
PostHogPersistedProperty["OptedOut"] = "opted_out";
|
|
904
954
|
PostHogPersistedProperty["SessionId"] = "session_id";
|
|
955
|
+
PostHogPersistedProperty["SessionStartTimestamp"] = "session_start_timestamp";
|
|
905
956
|
PostHogPersistedProperty["SessionLastTimestamp"] = "session_timestamp";
|
|
906
957
|
PostHogPersistedProperty["PersonProperties"] = "person_properties";
|
|
907
958
|
PostHogPersistedProperty["GroupProperties"] = "group_properties";
|
|
@@ -1216,6 +1267,9 @@ function isTokenInRollout(token, percentage = 0, excludedHashes) {
|
|
|
1216
1267
|
const hashInt = parseInt(tokenHash, 16);
|
|
1217
1268
|
const hashFloat = hashInt / 0xffffffff;
|
|
1218
1269
|
return hashFloat < percentage;
|
|
1270
|
+
}
|
|
1271
|
+
function allSettled(promises) {
|
|
1272
|
+
return Promise.all(promises.map((p) => (p ?? Promise.resolve()).then((value) => ({ status: 'fulfilled', value }), (reason) => ({ status: 'rejected', reason }))));
|
|
1219
1273
|
}
|
|
1220
1274
|
|
|
1221
1275
|
// Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>
|
|
@@ -1960,6 +2014,7 @@ class PostHogCoreStateless {
|
|
|
1960
2014
|
...extraPayload,
|
|
1961
2015
|
}),
|
|
1962
2016
|
};
|
|
2017
|
+
this.logMsgIfDebug(() => console.log('PostHog Debug', 'Decide URL', url));
|
|
1963
2018
|
// Don't retry /decide API calls
|
|
1964
2019
|
return this.fetchWithRetry(url, fetchOptions, { retryCount: 0 }, this.featureFlagsRequestTimeoutMs)
|
|
1965
2020
|
.then((response) => response.json())
|
|
@@ -2077,7 +2132,7 @@ class PostHogCoreStateless {
|
|
|
2077
2132
|
async getSurveysStateless() {
|
|
2078
2133
|
await this._initPromise;
|
|
2079
2134
|
if (this.disableSurveys === true) {
|
|
2080
|
-
this.logMsgIfDebug(() => console.log('Loading surveys is disabled.'));
|
|
2135
|
+
this.logMsgIfDebug(() => console.log('PostHog Debug', 'Loading surveys is disabled.'));
|
|
2081
2136
|
return [];
|
|
2082
2137
|
}
|
|
2083
2138
|
const url = `${this.host}/api/surveys/?token=${this.apiKey}`;
|
|
@@ -2200,7 +2255,6 @@ class PostHogCoreStateless {
|
|
|
2200
2255
|
}
|
|
2201
2256
|
catch (err) {
|
|
2202
2257
|
this._events.emit('error', err);
|
|
2203
|
-
throw err;
|
|
2204
2258
|
}
|
|
2205
2259
|
}
|
|
2206
2260
|
prepareMessage(type, _message, options) {
|
|
@@ -2240,15 +2294,38 @@ class PostHogCoreStateless {
|
|
|
2240
2294
|
await logFlushError(err);
|
|
2241
2295
|
});
|
|
2242
2296
|
}
|
|
2297
|
+
/**
|
|
2298
|
+
* Flushes the queue
|
|
2299
|
+
*
|
|
2300
|
+
* This function will return a promise that will resolve when the flush is complete,
|
|
2301
|
+
* or reject if there was an error (for example if the server or network is down).
|
|
2302
|
+
*
|
|
2303
|
+
* If there is already a flush in progress, this function will wait for that flush to complete.
|
|
2304
|
+
*
|
|
2305
|
+
* It's recommended to do error handling in the callback of the promise.
|
|
2306
|
+
*
|
|
2307
|
+
* @example
|
|
2308
|
+
* posthog.flush().then(() => {
|
|
2309
|
+
* console.log('Flush complete')
|
|
2310
|
+
* }).catch((err) => {
|
|
2311
|
+
* console.error('Flush failed', err)
|
|
2312
|
+
* })
|
|
2313
|
+
*
|
|
2314
|
+
*
|
|
2315
|
+
* @throws PostHogFetchHttpError
|
|
2316
|
+
* @throws PostHogFetchNetworkError
|
|
2317
|
+
* @throws Error
|
|
2318
|
+
*/
|
|
2243
2319
|
async flush() {
|
|
2244
2320
|
// Wait for the current flush operation to finish (regardless of success or failure), then try to flush again.
|
|
2245
2321
|
// Use allSettled instead of finally to be defensive around flush throwing errors immediately rather than rejecting.
|
|
2246
|
-
|
|
2322
|
+
// Use a custom allSettled implementation to avoid issues with patching Promise on RN
|
|
2323
|
+
const nextFlushPromise = allSettled([this.flushPromise]).then(() => {
|
|
2247
2324
|
return this._flush();
|
|
2248
2325
|
});
|
|
2249
2326
|
this.flushPromise = nextFlushPromise;
|
|
2250
2327
|
void this.addPendingPromise(nextFlushPromise);
|
|
2251
|
-
|
|
2328
|
+
allSettled([nextFlushPromise]).then(() => {
|
|
2252
2329
|
// If there are no others waiting to flush, clear the promise.
|
|
2253
2330
|
// We don't strictly need to do this, but it could make debugging easier
|
|
2254
2331
|
if (this.flushPromise === nextFlushPromise) {
|
|
@@ -2274,7 +2351,7 @@ class PostHogCoreStateless {
|
|
|
2274
2351
|
await this._initPromise;
|
|
2275
2352
|
let queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
|
|
2276
2353
|
if (!queue.length) {
|
|
2277
|
-
return
|
|
2354
|
+
return;
|
|
2278
2355
|
}
|
|
2279
2356
|
const sentMessages = [];
|
|
2280
2357
|
const originalQueueLength = queue.length;
|
|
@@ -2345,7 +2422,6 @@ class PostHogCoreStateless {
|
|
|
2345
2422
|
sentMessages.push(...batchMessages);
|
|
2346
2423
|
}
|
|
2347
2424
|
this._events.emit('flush', sentMessages);
|
|
2348
|
-
return sentMessages;
|
|
2349
2425
|
}
|
|
2350
2426
|
async fetchWithRetry(url, options, retryOptions, requestTimeout) {
|
|
2351
2427
|
var _a;
|
|
@@ -2355,7 +2431,14 @@ class PostHogCoreStateless {
|
|
|
2355
2431
|
return ctrl.signal;
|
|
2356
2432
|
});
|
|
2357
2433
|
const body = options.body ? options.body : '';
|
|
2358
|
-
|
|
2434
|
+
let reqByteLength = -1;
|
|
2435
|
+
try {
|
|
2436
|
+
reqByteLength = Buffer.byteLength(body, STRING_FORMAT);
|
|
2437
|
+
}
|
|
2438
|
+
catch {
|
|
2439
|
+
const encoded = new TextEncoder().encode(body);
|
|
2440
|
+
reqByteLength = encoded.length;
|
|
2441
|
+
}
|
|
2359
2442
|
return await retriable(async () => {
|
|
2360
2443
|
let res = null;
|
|
2361
2444
|
try {
|
|
@@ -2901,12 +2984,12 @@ class FeatureFlagsPoller {
|
|
|
2901
2984
|
case 200:
|
|
2902
2985
|
{
|
|
2903
2986
|
// Process successful response
|
|
2904
|
-
const responseJson = await res.json();
|
|
2987
|
+
const responseJson = (await res.json()) ?? {};
|
|
2905
2988
|
if (!('flags' in responseJson)) {
|
|
2906
2989
|
this.onError?.(new Error(`Invalid response when getting feature flags: ${JSON.stringify(responseJson)}`));
|
|
2907
2990
|
return;
|
|
2908
2991
|
}
|
|
2909
|
-
this.featureFlags = responseJson.flags
|
|
2992
|
+
this.featureFlags = responseJson.flags ?? [];
|
|
2910
2993
|
this.featureFlagsByKey = this.featureFlags.reduce((acc, curr) => (acc[curr.key] = curr, acc), {});
|
|
2911
2994
|
this.groupTypeMapping = responseJson.group_type_mapping || {};
|
|
2912
2995
|
this.cohorts = responseJson.cohorts || {};
|