posthog-js-lite 2.6.1 → 3.0.0-beta.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 +13 -0
- package/lib/index.cjs.js +995 -1149
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +65 -35
- package/lib/index.esm.js +995 -1149
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-core/src/index.d.ts +44 -30
- package/lib/posthog-core/src/types.d.ts +19 -3
- package/lib/posthog-core/src/utils.d.ts +5 -4
- package/lib/posthog-core/src/vendor/uuidv7.d.ts +179 -0
- package/lib/posthog-web/src/types.d.ts +2 -2
- package/package.json +1 -1
- package/src/types.ts +2 -2
- package/test/posthog-web.spec.ts +6 -2
- package/tsconfig.json +1 -1
package/lib/index.cjs.js
CHANGED
|
@@ -2,148 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
/******************************************************************************
|
|
6
|
-
Copyright (c) Microsoft Corporation.
|
|
7
|
-
|
|
8
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
9
|
-
purpose with or without fee is hereby granted.
|
|
10
|
-
|
|
11
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
12
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
13
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
14
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
15
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
16
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
17
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
18
|
-
***************************************************************************** */
|
|
19
|
-
/* global Reflect, Promise */
|
|
20
|
-
var extendStatics = function (d, b) {
|
|
21
|
-
extendStatics = Object.setPrototypeOf ||
|
|
22
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
23
|
-
function (d, b) { for (var p in b)
|
|
24
|
-
if (Object.prototype.hasOwnProperty.call(b, p))
|
|
25
|
-
d[p] = b[p]; };
|
|
26
|
-
return extendStatics(d, b);
|
|
27
|
-
};
|
|
28
|
-
function __extends(d, b) {
|
|
29
|
-
if (typeof b !== "function" && b !== null)
|
|
30
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
31
|
-
extendStatics(d, b);
|
|
32
|
-
function __() { this.constructor = d; }
|
|
33
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
34
|
-
}
|
|
35
|
-
var __assign = function () {
|
|
36
|
-
__assign = Object.assign || function __assign(t) {
|
|
37
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
38
|
-
s = arguments[i];
|
|
39
|
-
for (var p in s)
|
|
40
|
-
if (Object.prototype.hasOwnProperty.call(s, p))
|
|
41
|
-
t[p] = s[p];
|
|
42
|
-
}
|
|
43
|
-
return t;
|
|
44
|
-
};
|
|
45
|
-
return __assign.apply(this, arguments);
|
|
46
|
-
};
|
|
47
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
48
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
49
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
50
|
-
function fulfilled(value) { try {
|
|
51
|
-
step(generator.next(value));
|
|
52
|
-
}
|
|
53
|
-
catch (e) {
|
|
54
|
-
reject(e);
|
|
55
|
-
} }
|
|
56
|
-
function rejected(value) { try {
|
|
57
|
-
step(generator["throw"](value));
|
|
58
|
-
}
|
|
59
|
-
catch (e) {
|
|
60
|
-
reject(e);
|
|
61
|
-
} }
|
|
62
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
63
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
function __generator(thisArg, body) {
|
|
67
|
-
var _ = { label: 0, sent: function () { if (t[0] & 1)
|
|
68
|
-
throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
69
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
|
|
70
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
71
|
-
function step(op) {
|
|
72
|
-
if (f)
|
|
73
|
-
throw new TypeError("Generator is already executing.");
|
|
74
|
-
while (_)
|
|
75
|
-
try {
|
|
76
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
|
|
77
|
-
return t;
|
|
78
|
-
if (y = 0, t)
|
|
79
|
-
op = [op[0] & 2, t.value];
|
|
80
|
-
switch (op[0]) {
|
|
81
|
-
case 0:
|
|
82
|
-
case 1:
|
|
83
|
-
t = op;
|
|
84
|
-
break;
|
|
85
|
-
case 4:
|
|
86
|
-
_.label++;
|
|
87
|
-
return { value: op[1], done: false };
|
|
88
|
-
case 5:
|
|
89
|
-
_.label++;
|
|
90
|
-
y = op[1];
|
|
91
|
-
op = [0];
|
|
92
|
-
continue;
|
|
93
|
-
case 7:
|
|
94
|
-
op = _.ops.pop();
|
|
95
|
-
_.trys.pop();
|
|
96
|
-
continue;
|
|
97
|
-
default:
|
|
98
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
99
|
-
_ = 0;
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
|
|
103
|
-
_.label = op[1];
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
if (op[0] === 6 && _.label < t[1]) {
|
|
107
|
-
_.label = t[1];
|
|
108
|
-
t = op;
|
|
109
|
-
break;
|
|
110
|
-
}
|
|
111
|
-
if (t && _.label < t[2]) {
|
|
112
|
-
_.label = t[2];
|
|
113
|
-
_.ops.push(op);
|
|
114
|
-
break;
|
|
115
|
-
}
|
|
116
|
-
if (t[2])
|
|
117
|
-
_.ops.pop();
|
|
118
|
-
_.trys.pop();
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
op = body.call(thisArg, _);
|
|
122
|
-
}
|
|
123
|
-
catch (e) {
|
|
124
|
-
op = [6, e];
|
|
125
|
-
y = 0;
|
|
126
|
-
}
|
|
127
|
-
finally {
|
|
128
|
-
f = t = 0;
|
|
129
|
-
}
|
|
130
|
-
if (op[0] & 5)
|
|
131
|
-
throw op[1];
|
|
132
|
-
return { value: op[0] ? op[1] : void 0, done: true };
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
function __spreadArray(to, from, pack) {
|
|
136
|
-
if (pack || arguments.length === 2)
|
|
137
|
-
for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
138
|
-
if (ar || !(i in from)) {
|
|
139
|
-
if (!ar)
|
|
140
|
-
ar = Array.prototype.slice.call(from, 0, i);
|
|
141
|
-
ar[i] = from[i];
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
145
|
-
}
|
|
146
|
-
|
|
147
5
|
var PostHogPersistedProperty;
|
|
148
6
|
(function (PostHogPersistedProperty) {
|
|
149
7
|
PostHogPersistedProperty["AnonymousId"] = "anonymous_id";
|
|
@@ -168,48 +26,27 @@ function assert(truthyValue, message) {
|
|
|
168
26
|
}
|
|
169
27
|
}
|
|
170
28
|
function removeTrailingSlash(url) {
|
|
171
|
-
return url
|
|
29
|
+
return url?.replace(/\/+$/, '');
|
|
172
30
|
}
|
|
173
|
-
function retriable(fn, props) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return [4 /*yield*/, new Promise(function (r) { return setTimeout(r, retryDelay); })];
|
|
189
|
-
case 2:
|
|
190
|
-
// don't wait when it's the last try
|
|
191
|
-
_d.sent();
|
|
192
|
-
_d.label = 3;
|
|
193
|
-
case 3:
|
|
194
|
-
_d.trys.push([3, 5, , 6]);
|
|
195
|
-
return [4 /*yield*/, fn()];
|
|
196
|
-
case 4:
|
|
197
|
-
res = _d.sent();
|
|
198
|
-
return [2 /*return*/, res];
|
|
199
|
-
case 5:
|
|
200
|
-
e_1 = _d.sent();
|
|
201
|
-
lastError = e_1;
|
|
202
|
-
if (!retryCheck(e_1)) {
|
|
203
|
-
throw e_1;
|
|
204
|
-
}
|
|
205
|
-
return [3 /*break*/, 6];
|
|
206
|
-
case 6:
|
|
207
|
-
i++;
|
|
208
|
-
return [3 /*break*/, 1];
|
|
209
|
-
case 7: throw lastError;
|
|
31
|
+
async function retriable(fn, props) {
|
|
32
|
+
let lastError = null;
|
|
33
|
+
for (let i = 0; i < props.retryCount + 1; i++) {
|
|
34
|
+
if (i > 0) {
|
|
35
|
+
// don't wait when it's the last try
|
|
36
|
+
await new Promise((r) => setTimeout(r, props.retryDelay));
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const res = await fn();
|
|
40
|
+
return res;
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
lastError = e;
|
|
44
|
+
if (!props.retryCheck(e)) {
|
|
45
|
+
throw e;
|
|
210
46
|
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw lastError;
|
|
213
50
|
}
|
|
214
51
|
function currentTimestamp() {
|
|
215
52
|
return new Date().getTime();
|
|
@@ -220,9 +57,9 @@ function currentISOTime() {
|
|
|
220
57
|
function safeSetTimeout(fn, timeout) {
|
|
221
58
|
// NOTE: we use this so rarely that it is totally fine to do `safeSetTimeout(fn, 0)``
|
|
222
59
|
// rather than setImmediate.
|
|
223
|
-
|
|
60
|
+
const t = setTimeout(fn, timeout);
|
|
224
61
|
// We unref if available to prevent Node.js hanging on exit
|
|
225
|
-
|
|
62
|
+
t?.unref && t?.unref();
|
|
226
63
|
return t;
|
|
227
64
|
}
|
|
228
65
|
|
|
@@ -236,24 +73,24 @@ function safeSetTimeout(fn, timeout) {
|
|
|
236
73
|
//
|
|
237
74
|
// LZ-based compression algorithm, version 1.4.4
|
|
238
75
|
// private property
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
76
|
+
const f = String.fromCharCode;
|
|
77
|
+
const keyStrBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
78
|
+
const baseReverseDic = {};
|
|
242
79
|
function getBaseValue(alphabet, character) {
|
|
243
80
|
if (!baseReverseDic[alphabet]) {
|
|
244
81
|
baseReverseDic[alphabet] = {};
|
|
245
|
-
for (
|
|
82
|
+
for (let i = 0; i < alphabet.length; i++) {
|
|
246
83
|
baseReverseDic[alphabet][alphabet.charAt(i)] = i;
|
|
247
84
|
}
|
|
248
85
|
}
|
|
249
86
|
return baseReverseDic[alphabet][character];
|
|
250
87
|
}
|
|
251
|
-
|
|
88
|
+
const LZString = {
|
|
252
89
|
compressToBase64: function (input) {
|
|
253
90
|
if (input == null) {
|
|
254
91
|
return '';
|
|
255
92
|
}
|
|
256
|
-
|
|
93
|
+
const res = LZString._compress(input, 6, function (a) {
|
|
257
94
|
return keyStrBase64.charAt(a);
|
|
258
95
|
});
|
|
259
96
|
switch (res.length % 4 // To produce valid Base64
|
|
@@ -289,8 +126,8 @@ var LZString = {
|
|
|
289
126
|
if (uncompressed == null) {
|
|
290
127
|
return '';
|
|
291
128
|
}
|
|
292
|
-
|
|
293
|
-
|
|
129
|
+
const context_dictionary = {}, context_dictionaryToCreate = {}, context_data = [];
|
|
130
|
+
let i, value, context_c = '', context_wc = '', context_w = '', context_enlargeIn = 2, // Compensate for the first entry which should not count
|
|
294
131
|
context_dictSize = 3, context_numBits = 2, context_data_val = 0, context_data_position = 0, ii;
|
|
295
132
|
for (ii = 0; ii < uncompressed.length; ii += 1) {
|
|
296
133
|
context_c = uncompressed.charAt(ii);
|
|
@@ -514,8 +351,8 @@ var LZString = {
|
|
|
514
351
|
});
|
|
515
352
|
},
|
|
516
353
|
_decompress: function (length, resetValue, getNextValue) {
|
|
517
|
-
|
|
518
|
-
|
|
354
|
+
const dictionary = [], result = [], data = { val: getNextValue(0), position: resetValue, index: 1 };
|
|
355
|
+
let enlargeIn = 4, dictSize = 4, numBits = 3, entry = '', i, w, bits, resb, maxpower, power, c;
|
|
519
356
|
for (i = 0; i < 3; i += 1) {
|
|
520
357
|
dictionary[i] = i;
|
|
521
358
|
}
|
|
@@ -657,34 +494,32 @@ var LZString = {
|
|
|
657
494
|
},
|
|
658
495
|
};
|
|
659
496
|
|
|
660
|
-
|
|
661
|
-
|
|
497
|
+
class SimpleEventEmitter {
|
|
498
|
+
constructor() {
|
|
662
499
|
this.events = {};
|
|
663
500
|
this.events = {};
|
|
664
501
|
}
|
|
665
|
-
|
|
666
|
-
var _this = this;
|
|
502
|
+
on(event, listener) {
|
|
667
503
|
if (!this.events[event]) {
|
|
668
504
|
this.events[event] = [];
|
|
669
505
|
}
|
|
670
506
|
this.events[event].push(listener);
|
|
671
|
-
return
|
|
672
|
-
|
|
507
|
+
return () => {
|
|
508
|
+
this.events[event] = this.events[event].filter((x) => x !== listener);
|
|
673
509
|
};
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
for (
|
|
677
|
-
var listener = _a[_i];
|
|
510
|
+
}
|
|
511
|
+
emit(event, payload) {
|
|
512
|
+
for (const listener of this.events[event] || []) {
|
|
678
513
|
listener(payload);
|
|
679
514
|
}
|
|
680
|
-
for (
|
|
681
|
-
var listener = _c[_b];
|
|
515
|
+
for (const listener of this.events['*'] || []) {
|
|
682
516
|
listener(event, payload);
|
|
683
517
|
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
}());
|
|
518
|
+
}
|
|
519
|
+
}
|
|
687
520
|
|
|
521
|
+
// vendor from: https://github.com/LiosK/uuidv7/blob/f30b7a7faff73afbce0b27a46c638310f96912ba/src/index.ts
|
|
522
|
+
// https://github.com/LiosK/uuidv7#license
|
|
688
523
|
/**
|
|
689
524
|
* uuidv7: An experimental implementation of the proposed UUID Version 7
|
|
690
525
|
*
|
|
@@ -692,11 +527,11 @@ var SimpleEventEmitter = /** @class */ (function () {
|
|
|
692
527
|
* @copyright 2021-2023 LiosK
|
|
693
528
|
* @packageDocumentation
|
|
694
529
|
*/
|
|
695
|
-
|
|
530
|
+
const DIGITS = "0123456789abcdef";
|
|
696
531
|
/** Represents a UUID as a 16-byte byte array. */
|
|
697
|
-
|
|
532
|
+
class UUID {
|
|
698
533
|
/** @param bytes - The 16-byte byte array representation. */
|
|
699
|
-
|
|
534
|
+
constructor(bytes) {
|
|
700
535
|
this.bytes = bytes;
|
|
701
536
|
}
|
|
702
537
|
/**
|
|
@@ -708,14 +543,14 @@ var UUID = /** @class */ (function () {
|
|
|
708
543
|
*
|
|
709
544
|
* @throws TypeError if the length of the argument is not 16.
|
|
710
545
|
*/
|
|
711
|
-
|
|
546
|
+
static ofInner(bytes) {
|
|
712
547
|
if (bytes.length !== 16) {
|
|
713
548
|
throw new TypeError("not 128-bit length");
|
|
714
549
|
}
|
|
715
550
|
else {
|
|
716
551
|
return new UUID(bytes);
|
|
717
552
|
}
|
|
718
|
-
}
|
|
553
|
+
}
|
|
719
554
|
/**
|
|
720
555
|
* Builds a byte array from UUIDv7 field values.
|
|
721
556
|
*
|
|
@@ -725,7 +560,7 @@ var UUID = /** @class */ (function () {
|
|
|
725
560
|
* @param randBLo - The lower 32 bits of 62-bit `rand_b` field value.
|
|
726
561
|
* @throws RangeError if any field value is out of the specified range.
|
|
727
562
|
*/
|
|
728
|
-
|
|
563
|
+
static fromFieldsV7(unixTsMs, randA, randBHi, randBLo) {
|
|
729
564
|
if (!Number.isInteger(unixTsMs) ||
|
|
730
565
|
!Number.isInteger(randA) ||
|
|
731
566
|
!Number.isInteger(randBHi) ||
|
|
@@ -740,12 +575,12 @@ var UUID = /** @class */ (function () {
|
|
|
740
575
|
randBLo > 4294967295) {
|
|
741
576
|
throw new RangeError("invalid field value");
|
|
742
577
|
}
|
|
743
|
-
|
|
744
|
-
bytes[0] = unixTsMs /
|
|
745
|
-
bytes[1] = unixTsMs /
|
|
746
|
-
bytes[2] = unixTsMs /
|
|
747
|
-
bytes[3] = unixTsMs /
|
|
748
|
-
bytes[4] = unixTsMs /
|
|
578
|
+
const bytes = new Uint8Array(16);
|
|
579
|
+
bytes[0] = unixTsMs / 2 ** 40;
|
|
580
|
+
bytes[1] = unixTsMs / 2 ** 32;
|
|
581
|
+
bytes[2] = unixTsMs / 2 ** 24;
|
|
582
|
+
bytes[3] = unixTsMs / 2 ** 16;
|
|
583
|
+
bytes[4] = unixTsMs / 2 ** 8;
|
|
749
584
|
bytes[5] = unixTsMs;
|
|
750
585
|
bytes[6] = 0x70 | (randA >>> 8);
|
|
751
586
|
bytes[7] = randA;
|
|
@@ -758,7 +593,7 @@ var UUID = /** @class */ (function () {
|
|
|
758
593
|
bytes[14] = randBLo >>> 8;
|
|
759
594
|
bytes[15] = randBLo;
|
|
760
595
|
return new UUID(bytes);
|
|
761
|
-
}
|
|
596
|
+
}
|
|
762
597
|
/**
|
|
763
598
|
* Builds a byte array from a string representation.
|
|
764
599
|
*
|
|
@@ -773,33 +608,38 @@ var UUID = /** @class */ (function () {
|
|
|
773
608
|
*
|
|
774
609
|
* @throws SyntaxError if the argument could not parse as a valid UUID string.
|
|
775
610
|
*/
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
var hex = undefined;
|
|
611
|
+
static parse(uuid) {
|
|
612
|
+
let hex = undefined;
|
|
779
613
|
switch (uuid.length) {
|
|
780
614
|
case 32:
|
|
781
|
-
hex =
|
|
615
|
+
hex = /^[0-9a-f]{32}$/i.exec(uuid)?.[0];
|
|
782
616
|
break;
|
|
783
617
|
case 36:
|
|
784
618
|
hex =
|
|
785
|
-
|
|
786
|
-
.exec(uuid)
|
|
619
|
+
/^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$/i
|
|
620
|
+
.exec(uuid)
|
|
621
|
+
?.slice(1, 6)
|
|
622
|
+
.join("");
|
|
787
623
|
break;
|
|
788
624
|
case 38:
|
|
789
625
|
hex =
|
|
790
|
-
|
|
791
|
-
.exec(uuid)
|
|
626
|
+
/^\{([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})\}$/i
|
|
627
|
+
.exec(uuid)
|
|
628
|
+
?.slice(1, 6)
|
|
629
|
+
.join("");
|
|
792
630
|
break;
|
|
793
631
|
case 45:
|
|
794
632
|
hex =
|
|
795
|
-
|
|
796
|
-
.exec(uuid)
|
|
633
|
+
/^urn:uuid:([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})$/i
|
|
634
|
+
.exec(uuid)
|
|
635
|
+
?.slice(1, 6)
|
|
636
|
+
.join("");
|
|
797
637
|
break;
|
|
798
638
|
}
|
|
799
639
|
if (hex) {
|
|
800
|
-
|
|
801
|
-
for (
|
|
802
|
-
|
|
640
|
+
const inner = new Uint8Array(16);
|
|
641
|
+
for (let i = 0; i < 16; i += 4) {
|
|
642
|
+
const n = parseInt(hex.substring(2 * i, 2 * i + 8), 16);
|
|
803
643
|
inner[i + 0] = n >>> 24;
|
|
804
644
|
inner[i + 1] = n >>> 16;
|
|
805
645
|
inner[i + 2] = n >>> 8;
|
|
@@ -810,14 +650,14 @@ var UUID = /** @class */ (function () {
|
|
|
810
650
|
else {
|
|
811
651
|
throw new SyntaxError("could not parse UUID string");
|
|
812
652
|
}
|
|
813
|
-
}
|
|
653
|
+
}
|
|
814
654
|
/**
|
|
815
655
|
* @returns The 8-4-4-4-12 canonical hexadecimal string representation
|
|
816
656
|
* (`0189dcd5-5311-7d40-8db0-9496a2eef37b`).
|
|
817
657
|
*/
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
for (
|
|
658
|
+
toString() {
|
|
659
|
+
let text = "";
|
|
660
|
+
for (let i = 0; i < this.bytes.length; i++) {
|
|
821
661
|
text += DIGITS.charAt(this.bytes[i] >>> 4);
|
|
822
662
|
text += DIGITS.charAt(this.bytes[i] & 0xf);
|
|
823
663
|
if (i === 3 || i === 5 || i === 7 || i === 9) {
|
|
@@ -825,23 +665,23 @@ var UUID = /** @class */ (function () {
|
|
|
825
665
|
}
|
|
826
666
|
}
|
|
827
667
|
return text;
|
|
828
|
-
}
|
|
668
|
+
}
|
|
829
669
|
/**
|
|
830
670
|
* @returns The 32-digit hexadecimal representation without hyphens
|
|
831
671
|
* (`0189dcd553117d408db09496a2eef37b`).
|
|
832
672
|
*/
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
for (
|
|
673
|
+
toHex() {
|
|
674
|
+
let text = "";
|
|
675
|
+
for (let i = 0; i < this.bytes.length; i++) {
|
|
836
676
|
text += DIGITS.charAt(this.bytes[i] >>> 4);
|
|
837
677
|
text += DIGITS.charAt(this.bytes[i] & 0xf);
|
|
838
678
|
}
|
|
839
679
|
return text;
|
|
840
|
-
}
|
|
680
|
+
}
|
|
841
681
|
/** @returns The 8-4-4-4-12 canonical hexadecimal string representation. */
|
|
842
|
-
|
|
682
|
+
toJSON() {
|
|
843
683
|
return this.toString();
|
|
844
|
-
}
|
|
684
|
+
}
|
|
845
685
|
/**
|
|
846
686
|
* Reports the variant field value of the UUID or, if appropriate, "NIL" or
|
|
847
687
|
* "MAX".
|
|
@@ -850,57 +690,56 @@ var UUID = /** @class */ (function () {
|
|
|
850
690
|
* the Nil or Max UUID, although the Nil and Max UUIDs are technically
|
|
851
691
|
* subsumed under the variants `0b0` and `0b111`, respectively.
|
|
852
692
|
*/
|
|
853
|
-
|
|
854
|
-
|
|
693
|
+
getVariant() {
|
|
694
|
+
const n = this.bytes[8] >>> 4;
|
|
855
695
|
if (n < 0) {
|
|
856
696
|
throw new Error("unreachable");
|
|
857
697
|
}
|
|
858
|
-
else if (n <=
|
|
859
|
-
return this.bytes.every(
|
|
698
|
+
else if (n <= 0b0111) {
|
|
699
|
+
return this.bytes.every((e) => e === 0) ? "NIL" : "VAR_0";
|
|
860
700
|
}
|
|
861
|
-
else if (n <=
|
|
701
|
+
else if (n <= 0b1011) {
|
|
862
702
|
return "VAR_10";
|
|
863
703
|
}
|
|
864
|
-
else if (n <=
|
|
704
|
+
else if (n <= 0b1101) {
|
|
865
705
|
return "VAR_110";
|
|
866
706
|
}
|
|
867
|
-
else if (n <=
|
|
868
|
-
return this.bytes.every(
|
|
707
|
+
else if (n <= 0b1111) {
|
|
708
|
+
return this.bytes.every((e) => e === 0xff) ? "MAX" : "VAR_RESERVED";
|
|
869
709
|
}
|
|
870
710
|
else {
|
|
871
711
|
throw new Error("unreachable");
|
|
872
712
|
}
|
|
873
|
-
}
|
|
713
|
+
}
|
|
874
714
|
/**
|
|
875
715
|
* Returns the version field value of the UUID or `undefined` if the UUID does
|
|
876
716
|
* not have the variant field value of `0b10`.
|
|
877
717
|
*/
|
|
878
|
-
|
|
718
|
+
getVersion() {
|
|
879
719
|
return this.getVariant() === "VAR_10" ? this.bytes[6] >>> 4 : undefined;
|
|
880
|
-
}
|
|
720
|
+
}
|
|
881
721
|
/** Creates an object from `this`. */
|
|
882
|
-
|
|
722
|
+
clone() {
|
|
883
723
|
return new UUID(this.bytes.slice(0));
|
|
884
|
-
}
|
|
724
|
+
}
|
|
885
725
|
/** Returns true if `this` is equivalent to `other`. */
|
|
886
|
-
|
|
726
|
+
equals(other) {
|
|
887
727
|
return this.compareTo(other) === 0;
|
|
888
|
-
}
|
|
728
|
+
}
|
|
889
729
|
/**
|
|
890
730
|
* Returns a negative integer, zero, or positive integer if `this` is less
|
|
891
731
|
* than, equal to, or greater than `other`, respectively.
|
|
892
732
|
*/
|
|
893
|
-
|
|
894
|
-
for (
|
|
895
|
-
|
|
733
|
+
compareTo(other) {
|
|
734
|
+
for (let i = 0; i < 16; i++) {
|
|
735
|
+
const diff = this.bytes[i] - other.bytes[i];
|
|
896
736
|
if (diff !== 0) {
|
|
897
737
|
return Math.sign(diff);
|
|
898
738
|
}
|
|
899
739
|
}
|
|
900
740
|
return 0;
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
}());
|
|
741
|
+
}
|
|
742
|
+
}
|
|
904
743
|
/**
|
|
905
744
|
* Encapsulates the monotonic counter state.
|
|
906
745
|
*
|
|
@@ -910,16 +749,16 @@ var UUID = /** @class */ (function () {
|
|
|
910
749
|
* that is useful to absolutely guarantee the monotonically increasing order of
|
|
911
750
|
* generated UUIDs. See their respective documentation for details.
|
|
912
751
|
*/
|
|
913
|
-
|
|
752
|
+
class V7Generator {
|
|
914
753
|
/**
|
|
915
754
|
* Creates a generator object with the default random number generator, or
|
|
916
755
|
* with the specified one if passed as an argument. The specified random
|
|
917
756
|
* number generator should be cryptographically strong and securely seeded.
|
|
918
757
|
*/
|
|
919
|
-
|
|
758
|
+
constructor(randomNumberGenerator) {
|
|
920
759
|
this.timestamp = 0;
|
|
921
760
|
this.counter = 0;
|
|
922
|
-
this.random = randomNumberGenerator
|
|
761
|
+
this.random = randomNumberGenerator ?? getDefaultRandom();
|
|
923
762
|
}
|
|
924
763
|
/**
|
|
925
764
|
* Generates a new UUIDv7 object from the current timestamp, or resets the
|
|
@@ -935,9 +774,9 @@ var V7Generator = /** @class */ (function () {
|
|
|
935
774
|
* See {@link generateOrAbort} for the other mode of generation and
|
|
936
775
|
* {@link generateOrResetCore} for the low-level primitive.
|
|
937
776
|
*/
|
|
938
|
-
|
|
777
|
+
generate() {
|
|
939
778
|
return this.generateOrResetCore(Date.now(), 10000);
|
|
940
|
-
}
|
|
779
|
+
}
|
|
941
780
|
/**
|
|
942
781
|
* Generates a new UUIDv7 object from the current timestamp, or returns
|
|
943
782
|
* `undefined` upon significant timestamp rollback.
|
|
@@ -951,9 +790,9 @@ var V7Generator = /** @class */ (function () {
|
|
|
951
790
|
* See {@link generate} for the other mode of generation and
|
|
952
791
|
* {@link generateOrAbortCore} for the low-level primitive.
|
|
953
792
|
*/
|
|
954
|
-
|
|
793
|
+
generateOrAbort() {
|
|
955
794
|
return this.generateOrAbortCore(Date.now(), 10000);
|
|
956
|
-
}
|
|
795
|
+
}
|
|
957
796
|
/**
|
|
958
797
|
* Generates a new UUIDv7 object from the `unixTsMs` passed, or resets the
|
|
959
798
|
* generator upon significant timestamp rollback.
|
|
@@ -965,15 +804,15 @@ var V7Generator = /** @class */ (function () {
|
|
|
965
804
|
* considered significant. A suggested value is `10_000` (milliseconds).
|
|
966
805
|
* @throws RangeError if `unixTsMs` is not a 48-bit positive integer.
|
|
967
806
|
*/
|
|
968
|
-
|
|
969
|
-
|
|
807
|
+
generateOrResetCore(unixTsMs, rollbackAllowance) {
|
|
808
|
+
let value = this.generateOrAbortCore(unixTsMs, rollbackAllowance);
|
|
970
809
|
if (value === undefined) {
|
|
971
810
|
// reset state and resume
|
|
972
811
|
this.timestamp = 0;
|
|
973
812
|
value = this.generateOrAbortCore(unixTsMs, rollbackAllowance);
|
|
974
813
|
}
|
|
975
814
|
return value;
|
|
976
|
-
}
|
|
815
|
+
}
|
|
977
816
|
/**
|
|
978
817
|
* Generates a new UUIDv7 object from the `unixTsMs` passed, or returns
|
|
979
818
|
* `undefined` upon significant timestamp rollback.
|
|
@@ -985,8 +824,8 @@ var V7Generator = /** @class */ (function () {
|
|
|
985
824
|
* considered significant. A suggested value is `10_000` (milliseconds).
|
|
986
825
|
* @throws RangeError if `unixTsMs` is not a 48-bit positive integer.
|
|
987
826
|
*/
|
|
988
|
-
|
|
989
|
-
|
|
827
|
+
generateOrAbortCore(unixTsMs, rollbackAllowance) {
|
|
828
|
+
const MAX_COUNTER = 4398046511103;
|
|
990
829
|
if (!Number.isInteger(unixTsMs) ||
|
|
991
830
|
unixTsMs < 1 ||
|
|
992
831
|
unixTsMs > 281474976710655) {
|
|
@@ -1012,839 +851,861 @@ var V7Generator = /** @class */ (function () {
|
|
|
1012
851
|
// abort if clock went backwards to unbearable extent
|
|
1013
852
|
return undefined;
|
|
1014
853
|
}
|
|
1015
|
-
return UUID.fromFieldsV7(this.timestamp, Math.trunc(this.counter /
|
|
1016
|
-
}
|
|
854
|
+
return UUID.fromFieldsV7(this.timestamp, Math.trunc(this.counter / 2 ** 30), this.counter & (2 ** 30 - 1), this.random.nextUint32());
|
|
855
|
+
}
|
|
1017
856
|
/** Initializes the counter at a 42-bit random integer. */
|
|
1018
|
-
|
|
857
|
+
resetCounter() {
|
|
1019
858
|
this.counter =
|
|
1020
859
|
this.random.nextUint32() * 0x400 + (this.random.nextUint32() & 0x3ff);
|
|
1021
|
-
}
|
|
860
|
+
}
|
|
1022
861
|
/**
|
|
1023
862
|
* Generates a new UUIDv4 object utilizing the random number generator inside.
|
|
1024
863
|
*
|
|
1025
864
|
* @internal
|
|
1026
865
|
*/
|
|
1027
|
-
|
|
1028
|
-
|
|
866
|
+
generateV4() {
|
|
867
|
+
const bytes = new Uint8Array(Uint32Array.of(this.random.nextUint32(), this.random.nextUint32(), this.random.nextUint32(), this.random.nextUint32()).buffer);
|
|
1029
868
|
bytes[6] = 0x40 | (bytes[6] >>> 4);
|
|
1030
869
|
bytes[8] = 0x80 | (bytes[8] >>> 2);
|
|
1031
870
|
return UUID.ofInner(bytes);
|
|
1032
|
-
};
|
|
1033
|
-
return V7Generator;
|
|
1034
|
-
}());
|
|
1035
|
-
/** Returns the default random number generator available in the environment. */
|
|
1036
|
-
var getDefaultRandom = function () {
|
|
1037
|
-
// detect Web Crypto API
|
|
1038
|
-
if (typeof crypto !== "undefined" &&
|
|
1039
|
-
typeof crypto.getRandomValues !== "undefined") {
|
|
1040
|
-
return new BufferedCryptoRandom();
|
|
1041
|
-
}
|
|
1042
|
-
else {
|
|
1043
|
-
// fall back on Math.random() unless the flag is set to true
|
|
1044
|
-
if (typeof UUIDV7_DENY_WEAK_RNG !== "undefined" && UUIDV7_DENY_WEAK_RNG) {
|
|
1045
|
-
throw new Error("no cryptographically strong RNG available");
|
|
1046
|
-
}
|
|
1047
|
-
return {
|
|
1048
|
-
nextUint32: function () { return Math.trunc(Math.random() * 65536) * 65536 +
|
|
1049
|
-
Math.trunc(Math.random() * 65536); },
|
|
1050
|
-
};
|
|
1051
871
|
}
|
|
1052
|
-
}
|
|
1053
|
-
/**
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
872
|
+
}
|
|
873
|
+
/** A global flag to force use of cryptographically strong RNG. */
|
|
874
|
+
// declare const UUIDV7_DENY_WEAK_RNG: boolean;
|
|
875
|
+
/** Returns the default random number generator available in the environment. */
|
|
876
|
+
const getDefaultRandom = () => {
|
|
877
|
+
// fix: crypto isn't available in react-native, always use Math.random
|
|
878
|
+
// // detect Web Crypto API
|
|
879
|
+
// if (
|
|
880
|
+
// typeof crypto !== "undefined" &&
|
|
881
|
+
// typeof crypto.getRandomValues !== "undefined"
|
|
882
|
+
// ) {
|
|
883
|
+
// return new BufferedCryptoRandom();
|
|
884
|
+
// } else {
|
|
885
|
+
// // fall back on Math.random() unless the flag is set to true
|
|
886
|
+
// if (typeof UUIDV7_DENY_WEAK_RNG !== "undefined" && UUIDV7_DENY_WEAK_RNG) {
|
|
887
|
+
// throw new Error("no cryptographically strong RNG available");
|
|
888
|
+
// }
|
|
889
|
+
// return {
|
|
890
|
+
// nextUint32: (): number =>
|
|
891
|
+
// Math.trunc(Math.random() * 0x1_0000) * 0x1_0000 +
|
|
892
|
+
// Math.trunc(Math.random() * 0x1_0000),
|
|
893
|
+
// };
|
|
894
|
+
// }
|
|
895
|
+
return {
|
|
896
|
+
nextUint32: () => Math.trunc(Math.random() * 65536) * 65536 +
|
|
897
|
+
Math.trunc(Math.random() * 65536),
|
|
1069
898
|
};
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
899
|
+
};
|
|
900
|
+
// /**
|
|
901
|
+
// * Wraps `crypto.getRandomValues()` to enable buffering; this uses a small
|
|
902
|
+
// * buffer by default to avoid both unbearable throughput decline in some
|
|
903
|
+
// * environments and the waste of time and space for unused values.
|
|
904
|
+
// */
|
|
905
|
+
// class BufferedCryptoRandom {
|
|
906
|
+
// private readonly buffer = new Uint32Array(8);
|
|
907
|
+
// private cursor = 0xffff;
|
|
908
|
+
// nextUint32(): number {
|
|
909
|
+
// if (this.cursor >= this.buffer.length) {
|
|
910
|
+
// crypto.getRandomValues(this.buffer);
|
|
911
|
+
// this.cursor = 0;
|
|
912
|
+
// }
|
|
913
|
+
// return this.buffer[this.cursor++];
|
|
914
|
+
// }
|
|
915
|
+
// }
|
|
916
|
+
let defaultGenerator;
|
|
1073
917
|
/**
|
|
1074
918
|
* Generates a UUIDv7 string.
|
|
1075
919
|
*
|
|
1076
920
|
* @returns The 8-4-4-4-12 canonical hexadecimal string representation
|
|
1077
921
|
* ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx").
|
|
1078
922
|
*/
|
|
1079
|
-
|
|
923
|
+
const uuidv7 = () => uuidv7obj().toString();
|
|
1080
924
|
/** Generates a UUIDv7 object. */
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
}(Error));
|
|
1093
|
-
var PostHogFetchNetworkError = /** @class */ (function (_super) {
|
|
1094
|
-
__extends(PostHogFetchNetworkError, _super);
|
|
1095
|
-
function PostHogFetchNetworkError(error) {
|
|
1096
|
-
var _this =
|
|
925
|
+
const uuidv7obj = () => (defaultGenerator || (defaultGenerator = new V7Generator())).generate();
|
|
926
|
+
|
|
927
|
+
class PostHogFetchHttpError extends Error {
|
|
928
|
+
constructor(response) {
|
|
929
|
+
super('HTTP error while fetching PostHog: ' + response.status);
|
|
930
|
+
this.response = response;
|
|
931
|
+
this.name = 'PostHogFetchHttpError';
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
class PostHogFetchNetworkError extends Error {
|
|
935
|
+
constructor(error) {
|
|
1097
936
|
// TRICKY: "cause" is a newer property but is just ignored otherwise. Cast to any to ignore the type issue.
|
|
937
|
+
// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
|
|
1098
938
|
// @ts-ignore
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
return _this;
|
|
939
|
+
super('Network error while fetching PostHog', error instanceof Error ? { cause: error } : {});
|
|
940
|
+
this.error = error;
|
|
941
|
+
this.name = 'PostHogFetchNetworkError';
|
|
1103
942
|
}
|
|
1104
|
-
|
|
1105
|
-
}(Error));
|
|
943
|
+
}
|
|
1106
944
|
function isPostHogFetchError(err) {
|
|
1107
|
-
return typeof err === 'object' && (err
|
|
945
|
+
return typeof err === 'object' && (err instanceof PostHogFetchHttpError || err instanceof PostHogFetchNetworkError);
|
|
1108
946
|
}
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
var _a, _b, _c, _d, _e;
|
|
1112
|
-
this.debugMode = false;
|
|
947
|
+
class PostHogCoreStateless {
|
|
948
|
+
constructor(apiKey, options) {
|
|
1113
949
|
this.disableGeoip = true;
|
|
950
|
+
this.disabled = false;
|
|
951
|
+
this.defaultOptIn = true;
|
|
1114
952
|
this.pendingPromises = {};
|
|
1115
953
|
// internal
|
|
1116
954
|
this._events = new SimpleEventEmitter();
|
|
955
|
+
this._isInitialized = false;
|
|
1117
956
|
assert(apiKey, "You must pass your PostHog project's api key.");
|
|
1118
957
|
this.apiKey = apiKey;
|
|
1119
|
-
this.host = removeTrailingSlash(
|
|
1120
|
-
this.flushAt =
|
|
1121
|
-
this.flushInterval =
|
|
1122
|
-
this.captureMode =
|
|
958
|
+
this.host = removeTrailingSlash(options?.host || 'https://app.posthog.com');
|
|
959
|
+
this.flushAt = options?.flushAt ? Math.max(options?.flushAt, 1) : 20;
|
|
960
|
+
this.flushInterval = options?.flushInterval ?? 10000;
|
|
961
|
+
this.captureMode = options?.captureMode || 'form';
|
|
1123
962
|
// If enable is explicitly set to false we override the optout
|
|
1124
|
-
this.
|
|
963
|
+
this.defaultOptIn = options?.defaultOptIn ?? true;
|
|
1125
964
|
this._retryOptions = {
|
|
1126
|
-
retryCount:
|
|
1127
|
-
retryDelay:
|
|
965
|
+
retryCount: options?.fetchRetryCount ?? 3,
|
|
966
|
+
retryDelay: options?.fetchRetryDelay ?? 3000,
|
|
1128
967
|
retryCheck: isPostHogFetchError,
|
|
1129
968
|
};
|
|
1130
|
-
this.requestTimeout =
|
|
1131
|
-
this.
|
|
969
|
+
this.requestTimeout = options?.requestTimeout ?? 10000; // 10 seconds
|
|
970
|
+
this.featureFlagsRequestTimeoutMs = options?.featureFlagsRequestTimeoutMs ?? 3000; // 3 seconds
|
|
971
|
+
this.disableGeoip = options?.disableGeoip ?? true;
|
|
972
|
+
this.disabled = options?.disabled ?? false;
|
|
973
|
+
// Init promise allows the derived class to block calls until it is ready
|
|
974
|
+
this._initPromise = Promise.resolve();
|
|
975
|
+
this._isInitialized = true;
|
|
976
|
+
}
|
|
977
|
+
wrap(fn) {
|
|
978
|
+
if (this.disabled) {
|
|
979
|
+
if (this.isDebug) {
|
|
980
|
+
console.warn('[PostHog] The client is disabled');
|
|
981
|
+
}
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
if (this._isInitialized) {
|
|
985
|
+
// NOTE: We could also check for the "opt in" status here...
|
|
986
|
+
return fn();
|
|
987
|
+
}
|
|
988
|
+
this._initPromise.then(() => fn());
|
|
1132
989
|
}
|
|
1133
|
-
|
|
990
|
+
getCommonEventProperties() {
|
|
1134
991
|
return {
|
|
1135
992
|
$lib: this.getLibraryId(),
|
|
1136
993
|
$lib_version: this.getLibraryVersion(),
|
|
1137
994
|
};
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
this.
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
PostHogCoreStateless.prototype.on = function (event, cb) {
|
|
995
|
+
}
|
|
996
|
+
get optedOut() {
|
|
997
|
+
return this.getPersistedProperty(PostHogPersistedProperty.OptedOut) ?? !this.defaultOptIn;
|
|
998
|
+
}
|
|
999
|
+
async optIn() {
|
|
1000
|
+
this.wrap(() => {
|
|
1001
|
+
this.setPersistedProperty(PostHogPersistedProperty.OptedOut, false);
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
async optOut() {
|
|
1005
|
+
this.wrap(() => {
|
|
1006
|
+
this.setPersistedProperty(PostHogPersistedProperty.OptedOut, true);
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
on(event, cb) {
|
|
1154
1010
|
return this._events.on(event, cb);
|
|
1155
|
-
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
if (enabled === void 0) { enabled = true; }
|
|
1159
|
-
(_a = this.removeDebugCallback) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
1160
|
-
this.debugMode = enabled;
|
|
1011
|
+
}
|
|
1012
|
+
debug(enabled = true) {
|
|
1013
|
+
this.removeDebugCallback?.();
|
|
1161
1014
|
if (enabled) {
|
|
1162
|
-
|
|
1015
|
+
const removeDebugCallback = this.on('*', (event, payload) => console.log('PostHog Debug', event, payload));
|
|
1016
|
+
this.removeDebugCallback = () => {
|
|
1017
|
+
removeDebugCallback();
|
|
1018
|
+
this.removeDebugCallback = undefined;
|
|
1019
|
+
};
|
|
1163
1020
|
}
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1021
|
+
}
|
|
1022
|
+
get isDebug() {
|
|
1023
|
+
return !!this.removeDebugCallback;
|
|
1024
|
+
}
|
|
1025
|
+
buildPayload(payload) {
|
|
1166
1026
|
return {
|
|
1167
1027
|
distinct_id: payload.distinct_id,
|
|
1168
1028
|
event: payload.event,
|
|
1169
|
-
properties:
|
|
1029
|
+
properties: {
|
|
1030
|
+
...(payload.properties || {}),
|
|
1031
|
+
...this.getCommonEventProperties(), // Common PH props
|
|
1032
|
+
},
|
|
1170
1033
|
};
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
var promiseUUID = uuidv7();
|
|
1034
|
+
}
|
|
1035
|
+
addPendingPromise(promise) {
|
|
1036
|
+
const promiseUUID = uuidv7();
|
|
1175
1037
|
this.pendingPromises[promiseUUID] = promise;
|
|
1176
|
-
promise.finally(
|
|
1177
|
-
delete
|
|
1038
|
+
promise.finally(() => {
|
|
1039
|
+
delete this.pendingPromises[promiseUUID];
|
|
1178
1040
|
});
|
|
1179
|
-
}
|
|
1041
|
+
}
|
|
1180
1042
|
/***
|
|
1181
1043
|
*** TRACKING
|
|
1182
1044
|
***/
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
var payload = this.buildPayload({ distinct_id: distinctId, event: event, properties: properties });
|
|
1196
|
-
this.enqueue('capture', payload, options);
|
|
1197
|
-
return this;
|
|
1198
|
-
};
|
|
1199
|
-
PostHogCoreStateless.prototype.aliasStateless = function (alias, distinctId, properties, options) {
|
|
1200
|
-
var payload = this.buildPayload({
|
|
1201
|
-
event: '$create_alias',
|
|
1202
|
-
distinct_id: distinctId,
|
|
1203
|
-
properties: __assign(__assign({}, (properties || {})), { distinct_id: distinctId, alias: alias }),
|
|
1045
|
+
identifyStateless(distinctId, properties, options) {
|
|
1046
|
+
this.wrap(() => {
|
|
1047
|
+
// The properties passed to identifyStateless are event properties.
|
|
1048
|
+
// To add person properties, pass in all person properties to the `$set` key.
|
|
1049
|
+
const payload = {
|
|
1050
|
+
...this.buildPayload({
|
|
1051
|
+
distinct_id: distinctId,
|
|
1052
|
+
event: '$identify',
|
|
1053
|
+
properties,
|
|
1054
|
+
}),
|
|
1055
|
+
};
|
|
1056
|
+
this.enqueue('identify', payload, options);
|
|
1204
1057
|
});
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1058
|
+
}
|
|
1059
|
+
captureStateless(distinctId, event, properties, options) {
|
|
1060
|
+
this.wrap(() => {
|
|
1061
|
+
const payload = this.buildPayload({ distinct_id: distinctId, event, properties });
|
|
1062
|
+
this.enqueue('capture', payload, options);
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
aliasStateless(alias, distinctId, properties, options) {
|
|
1066
|
+
this.wrap(() => {
|
|
1067
|
+
const payload = this.buildPayload({
|
|
1068
|
+
event: '$create_alias',
|
|
1069
|
+
distinct_id: distinctId,
|
|
1070
|
+
properties: {
|
|
1071
|
+
...(properties || {}),
|
|
1072
|
+
distinct_id: distinctId,
|
|
1073
|
+
alias,
|
|
1074
|
+
},
|
|
1075
|
+
});
|
|
1076
|
+
this.enqueue('alias', payload, options);
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1208
1079
|
/***
|
|
1209
1080
|
*** GROUPS
|
|
1210
1081
|
***/
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1082
|
+
groupIdentifyStateless(groupType, groupKey, groupProperties, options, distinctId, eventProperties) {
|
|
1083
|
+
this.wrap(() => {
|
|
1084
|
+
const payload = this.buildPayload({
|
|
1085
|
+
distinct_id: distinctId || `$${groupType}_${groupKey}`,
|
|
1086
|
+
event: '$groupidentify',
|
|
1087
|
+
properties: {
|
|
1088
|
+
$group_type: groupType,
|
|
1089
|
+
$group_key: groupKey,
|
|
1090
|
+
$group_set: groupProperties || {},
|
|
1091
|
+
...(eventProperties || {}),
|
|
1092
|
+
},
|
|
1093
|
+
});
|
|
1094
|
+
this.enqueue('capture', payload, options);
|
|
1216
1095
|
});
|
|
1217
|
-
|
|
1218
|
-
return this;
|
|
1219
|
-
};
|
|
1096
|
+
}
|
|
1220
1097
|
/***
|
|
1221
1098
|
*** FEATURE FLAGS
|
|
1222
1099
|
***/
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
});
|
|
1245
|
-
});
|
|
1246
|
-
};
|
|
1247
|
-
PostHogCoreStateless.prototype.getFeatureFlagStateless = function (key, distinctId, groups, personProperties, groupProperties, disableGeoip) {
|
|
1248
|
-
if (groups === void 0) { groups = {}; }
|
|
1249
|
-
if (personProperties === void 0) { personProperties = {}; }
|
|
1250
|
-
if (groupProperties === void 0) { groupProperties = {}; }
|
|
1251
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1252
|
-
var featureFlags, response;
|
|
1253
|
-
return __generator(this, function (_a) {
|
|
1254
|
-
switch (_a.label) {
|
|
1255
|
-
case 0: return [4 /*yield*/, this.getFeatureFlagsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)];
|
|
1256
|
-
case 1:
|
|
1257
|
-
featureFlags = _a.sent();
|
|
1258
|
-
if (!featureFlags) {
|
|
1259
|
-
// If we haven't loaded flags yet, or errored out, we respond with undefined
|
|
1260
|
-
return [2 /*return*/, undefined];
|
|
1261
|
-
}
|
|
1262
|
-
response = featureFlags[key];
|
|
1263
|
-
// `/decide` v3 returns all flags
|
|
1264
|
-
if (response === undefined) {
|
|
1265
|
-
// For cases where the flag is unknown, return false
|
|
1266
|
-
response = false;
|
|
1267
|
-
}
|
|
1268
|
-
// If we have flags we either return the value (true or string) or false
|
|
1269
|
-
return [2 /*return*/, response];
|
|
1270
|
-
}
|
|
1271
|
-
});
|
|
1272
|
-
});
|
|
1273
|
-
};
|
|
1274
|
-
PostHogCoreStateless.prototype.getFeatureFlagPayloadStateless = function (key, distinctId, groups, personProperties, groupProperties, disableGeoip) {
|
|
1275
|
-
if (groups === void 0) { groups = {}; }
|
|
1276
|
-
if (personProperties === void 0) { personProperties = {}; }
|
|
1277
|
-
if (groupProperties === void 0) { groupProperties = {}; }
|
|
1278
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1279
|
-
var payloads, response;
|
|
1280
|
-
return __generator(this, function (_a) {
|
|
1281
|
-
switch (_a.label) {
|
|
1282
|
-
case 0: return [4 /*yield*/, this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)];
|
|
1283
|
-
case 1:
|
|
1284
|
-
payloads = _a.sent();
|
|
1285
|
-
if (!payloads) {
|
|
1286
|
-
return [2 /*return*/, undefined];
|
|
1287
|
-
}
|
|
1288
|
-
response = payloads[key];
|
|
1289
|
-
// Undefined means a loading or missing data issue. Null means evaluation happened and there was no match
|
|
1290
|
-
if (response === undefined) {
|
|
1291
|
-
return [2 /*return*/, null];
|
|
1292
|
-
}
|
|
1293
|
-
return [2 /*return*/, this._parsePayload(response)];
|
|
1294
|
-
}
|
|
1295
|
-
});
|
|
1296
|
-
});
|
|
1297
|
-
};
|
|
1298
|
-
PostHogCoreStateless.prototype.getFeatureFlagPayloadsStateless = function (distinctId, groups, personProperties, groupProperties, disableGeoip) {
|
|
1299
|
-
if (groups === void 0) { groups = {}; }
|
|
1300
|
-
if (personProperties === void 0) { personProperties = {}; }
|
|
1301
|
-
if (groupProperties === void 0) { groupProperties = {}; }
|
|
1302
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1303
|
-
var payloads;
|
|
1304
|
-
var _this = this;
|
|
1305
|
-
return __generator(this, function (_a) {
|
|
1306
|
-
switch (_a.label) {
|
|
1307
|
-
case 0: return [4 /*yield*/, this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)];
|
|
1308
|
-
case 1:
|
|
1309
|
-
payloads = (_a.sent()).payloads;
|
|
1310
|
-
if (payloads) {
|
|
1311
|
-
return [2 /*return*/, Object.fromEntries(Object.entries(payloads).map(function (_a) {
|
|
1312
|
-
var k = _a[0], v = _a[1];
|
|
1313
|
-
return [k, _this._parsePayload(v)];
|
|
1314
|
-
}))];
|
|
1315
|
-
}
|
|
1316
|
-
return [2 /*return*/, payloads];
|
|
1317
|
-
}
|
|
1318
|
-
});
|
|
1100
|
+
async getDecide(distinctId, groups = {}, personProperties = {}, groupProperties = {}, extraPayload = {}) {
|
|
1101
|
+
await this._initPromise;
|
|
1102
|
+
const url = `${this.host}/decide/?v=3`;
|
|
1103
|
+
const fetchOptions = {
|
|
1104
|
+
method: 'POST',
|
|
1105
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1106
|
+
body: JSON.stringify({
|
|
1107
|
+
token: this.apiKey,
|
|
1108
|
+
distinct_id: distinctId,
|
|
1109
|
+
groups,
|
|
1110
|
+
person_properties: personProperties,
|
|
1111
|
+
group_properties: groupProperties,
|
|
1112
|
+
...extraPayload,
|
|
1113
|
+
}),
|
|
1114
|
+
};
|
|
1115
|
+
// Don't retry /decide API calls
|
|
1116
|
+
return this.fetchWithRetry(url, fetchOptions, { retryCount: 0 }, this.featureFlagsRequestTimeoutMs)
|
|
1117
|
+
.then((response) => response.json())
|
|
1118
|
+
.catch((error) => {
|
|
1119
|
+
this._events.emit('error', error);
|
|
1120
|
+
return undefined;
|
|
1319
1121
|
});
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1122
|
+
}
|
|
1123
|
+
async getFeatureFlagStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1124
|
+
await this._initPromise;
|
|
1125
|
+
const featureFlags = await this.getFeatureFlagsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip);
|
|
1126
|
+
if (!featureFlags) {
|
|
1127
|
+
// If we haven't loaded flags yet, or errored out, we respond with undefined
|
|
1128
|
+
return undefined;
|
|
1129
|
+
}
|
|
1130
|
+
let response = featureFlags[key];
|
|
1131
|
+
// `/decide` v3 returns all flags
|
|
1132
|
+
if (response === undefined) {
|
|
1133
|
+
// For cases where the flag is unknown, return false
|
|
1134
|
+
response = false;
|
|
1135
|
+
}
|
|
1136
|
+
// If we have flags we either return the value (true or string) or false
|
|
1137
|
+
return response;
|
|
1138
|
+
}
|
|
1139
|
+
async getFeatureFlagPayloadStateless(key, distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1140
|
+
await this._initPromise;
|
|
1141
|
+
const payloads = await this.getFeatureFlagPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip);
|
|
1142
|
+
if (!payloads) {
|
|
1143
|
+
return undefined;
|
|
1144
|
+
}
|
|
1145
|
+
const response = payloads[key];
|
|
1146
|
+
// Undefined means a loading or missing data issue. Null means evaluation happened and there was no match
|
|
1147
|
+
if (response === undefined) {
|
|
1148
|
+
return null;
|
|
1149
|
+
}
|
|
1150
|
+
return this._parsePayload(response);
|
|
1151
|
+
}
|
|
1152
|
+
async getFeatureFlagPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1153
|
+
await this._initPromise;
|
|
1154
|
+
const payloads = (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)).payloads;
|
|
1155
|
+
if (payloads) {
|
|
1156
|
+
return Object.fromEntries(Object.entries(payloads).map(([k, v]) => [k, this._parsePayload(v)]));
|
|
1157
|
+
}
|
|
1158
|
+
return payloads;
|
|
1159
|
+
}
|
|
1160
|
+
_parsePayload(response) {
|
|
1322
1161
|
try {
|
|
1323
1162
|
return JSON.parse(response);
|
|
1324
1163
|
}
|
|
1325
|
-
catch
|
|
1164
|
+
catch {
|
|
1326
1165
|
return response;
|
|
1327
1166
|
}
|
|
1328
|
-
}
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
var extraPayload, decideResponse, flags, payloads;
|
|
1348
|
-
return __generator(this, function (_a) {
|
|
1349
|
-
switch (_a.label) {
|
|
1350
|
-
case 0:
|
|
1351
|
-
extraPayload = {};
|
|
1352
|
-
if (disableGeoip !== null && disableGeoip !== void 0 ? disableGeoip : this.disableGeoip) {
|
|
1353
|
-
extraPayload['geoip_disable'] = true;
|
|
1354
|
-
}
|
|
1355
|
-
return [4 /*yield*/, this.getDecide(distinctId, groups, personProperties, groupProperties, extraPayload)];
|
|
1356
|
-
case 1:
|
|
1357
|
-
decideResponse = _a.sent();
|
|
1358
|
-
flags = decideResponse === null || decideResponse === void 0 ? void 0 : decideResponse.featureFlags;
|
|
1359
|
-
payloads = decideResponse === null || decideResponse === void 0 ? void 0 : decideResponse.featureFlagPayloads;
|
|
1360
|
-
return [2 /*return*/, {
|
|
1361
|
-
flags: flags,
|
|
1362
|
-
payloads: payloads,
|
|
1363
|
-
}];
|
|
1364
|
-
}
|
|
1365
|
-
});
|
|
1366
|
-
});
|
|
1367
|
-
};
|
|
1167
|
+
}
|
|
1168
|
+
async getFeatureFlagsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1169
|
+
await this._initPromise;
|
|
1170
|
+
return (await this.getFeatureFlagsAndPayloadsStateless(distinctId, groups, personProperties, groupProperties, disableGeoip)).flags;
|
|
1171
|
+
}
|
|
1172
|
+
async getFeatureFlagsAndPayloadsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip) {
|
|
1173
|
+
await this._initPromise;
|
|
1174
|
+
const extraPayload = {};
|
|
1175
|
+
if (disableGeoip ?? this.disableGeoip) {
|
|
1176
|
+
extraPayload['geoip_disable'] = true;
|
|
1177
|
+
}
|
|
1178
|
+
const decideResponse = await this.getDecide(distinctId, groups, personProperties, groupProperties, extraPayload);
|
|
1179
|
+
const flags = decideResponse?.featureFlags;
|
|
1180
|
+
const payloads = decideResponse?.featureFlagPayloads;
|
|
1181
|
+
return {
|
|
1182
|
+
flags,
|
|
1183
|
+
payloads,
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1368
1186
|
/***
|
|
1369
1187
|
*** QUEUEING AND FLUSHING
|
|
1370
1188
|
***/
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
return;
|
|
1377
|
-
}
|
|
1378
|
-
var message = __assign(__assign({}, _message), { type: type, library: this.getLibraryId(), library_version: this.getLibraryVersion(), timestamp: (options === null || options === void 0 ? void 0 : options.timestamp) ? options === null || options === void 0 ? void 0 : options.timestamp : currentISOTime(), uuid: (options === null || options === void 0 ? void 0 : options.uuid) ? options.uuid : uuidv7() });
|
|
1379
|
-
var addGeoipDisableProperty = (_a = options === null || options === void 0 ? void 0 : options.disableGeoip) !== null && _a !== void 0 ? _a : this.disableGeoip;
|
|
1380
|
-
if (addGeoipDisableProperty) {
|
|
1381
|
-
if (!message.properties) {
|
|
1382
|
-
message.properties = {};
|
|
1189
|
+
enqueue(type, _message, options) {
|
|
1190
|
+
this.wrap(() => {
|
|
1191
|
+
if (this.optedOut) {
|
|
1192
|
+
this._events.emit(type, `Library is disabled. Not sending event. To re-enable, call posthog.optIn()`);
|
|
1193
|
+
return;
|
|
1383
1194
|
}
|
|
1384
|
-
message
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1195
|
+
const message = {
|
|
1196
|
+
..._message,
|
|
1197
|
+
type: type,
|
|
1198
|
+
library: this.getLibraryId(),
|
|
1199
|
+
library_version: this.getLibraryVersion(),
|
|
1200
|
+
timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
|
|
1201
|
+
uuid: options?.uuid ? options.uuid : uuidv7(),
|
|
1202
|
+
};
|
|
1203
|
+
const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
|
|
1204
|
+
if (addGeoipDisableProperty) {
|
|
1205
|
+
if (!message.properties) {
|
|
1206
|
+
message.properties = {};
|
|
1207
|
+
}
|
|
1208
|
+
message['properties']['$geoip_disable'] = true;
|
|
1209
|
+
}
|
|
1210
|
+
if (message.distinctId) {
|
|
1211
|
+
message.distinct_id = message.distinctId;
|
|
1212
|
+
delete message.distinctId;
|
|
1213
|
+
}
|
|
1214
|
+
const queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
|
|
1215
|
+
queue.push({ message });
|
|
1216
|
+
this.setPersistedProperty(PostHogPersistedProperty.Queue, queue);
|
|
1217
|
+
this._events.emit(type, message);
|
|
1218
|
+
// Flush queued events if we meet the flushAt length
|
|
1219
|
+
if (queue.length >= this.flushAt) {
|
|
1220
|
+
this.flush();
|
|
1221
|
+
}
|
|
1222
|
+
if (this.flushInterval && !this._flushTimer) {
|
|
1223
|
+
this._flushTimer = safeSetTimeout(() => this.flush(), this.flushInterval);
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
async flushAsync() {
|
|
1228
|
+
await this._initPromise;
|
|
1229
|
+
return new Promise((resolve, reject) => {
|
|
1230
|
+
this.flush((err, data) => {
|
|
1406
1231
|
return err ? reject(err) : resolve(data);
|
|
1407
1232
|
});
|
|
1408
1233
|
});
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
}
|
|
1416
|
-
var queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
|
|
1417
|
-
if (!queue.length) {
|
|
1418
|
-
return callback === null || callback === void 0 ? void 0 : callback();
|
|
1419
|
-
}
|
|
1420
|
-
var items = queue.splice(0, this.flushAt);
|
|
1421
|
-
this.setPersistedProperty(PostHogPersistedProperty.Queue, queue);
|
|
1422
|
-
var messages = items.map(function (item) { return item.message; });
|
|
1423
|
-
var data = {
|
|
1424
|
-
api_key: this.apiKey,
|
|
1425
|
-
batch: messages,
|
|
1426
|
-
sent_at: currentISOTime(),
|
|
1427
|
-
};
|
|
1428
|
-
var done = function (err) {
|
|
1429
|
-
if (err) {
|
|
1430
|
-
_this._events.emit('error', err);
|
|
1234
|
+
}
|
|
1235
|
+
flush(callback) {
|
|
1236
|
+
this.wrap(() => {
|
|
1237
|
+
if (this._flushTimer) {
|
|
1238
|
+
clearTimeout(this._flushTimer);
|
|
1239
|
+
this._flushTimer = null;
|
|
1431
1240
|
}
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
// Don't set the user agent if we're not on a browser. The latest spec allows
|
|
1436
|
-
// the User-Agent header (see https://fetch.spec.whatwg.org/#terminology-headers
|
|
1437
|
-
// and https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader),
|
|
1438
|
-
// but browsers such as Chrome and Safari have not caught up.
|
|
1439
|
-
this.getCustomUserAgent();
|
|
1440
|
-
var payload = JSON.stringify(data);
|
|
1441
|
-
var url = this.captureMode === 'form'
|
|
1442
|
-
? "".concat(this.host, "/e/?ip=1&_=").concat(currentTimestamp(), "&v=").concat(this.getLibraryVersion())
|
|
1443
|
-
: "".concat(this.host, "/batch/");
|
|
1444
|
-
var fetchOptions = this.captureMode === 'form'
|
|
1445
|
-
? {
|
|
1446
|
-
method: 'POST',
|
|
1447
|
-
mode: 'no-cors',
|
|
1448
|
-
credentials: 'omit',
|
|
1449
|
-
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
1450
|
-
body: "data=".concat(encodeURIComponent(LZString.compressToBase64(payload)), "&compression=lz64"),
|
|
1241
|
+
const queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
|
|
1242
|
+
if (!queue.length) {
|
|
1243
|
+
return callback?.();
|
|
1451
1244
|
}
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1245
|
+
const items = queue.splice(0, this.flushAt);
|
|
1246
|
+
this.setPersistedProperty(PostHogPersistedProperty.Queue, queue);
|
|
1247
|
+
const messages = items.map((item) => item.message);
|
|
1248
|
+
const data = {
|
|
1249
|
+
api_key: this.apiKey,
|
|
1250
|
+
batch: messages,
|
|
1251
|
+
sent_at: currentISOTime(),
|
|
1456
1252
|
};
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
.catch(function (err) {
|
|
1461
|
-
done(err);
|
|
1462
|
-
}));
|
|
1463
|
-
};
|
|
1464
|
-
PostHogCoreStateless.prototype.fetchWithRetry = function (url, options, retryOptions) {
|
|
1465
|
-
var _a;
|
|
1466
|
-
var _b;
|
|
1467
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
1468
|
-
var _this = this;
|
|
1469
|
-
return __generator(this, function (_c) {
|
|
1470
|
-
switch (_c.label) {
|
|
1471
|
-
case 0:
|
|
1472
|
-
(_a = (_b = AbortSignal).timeout) !== null && _a !== void 0 ? _a : (_b.timeout = function timeout(ms) {
|
|
1473
|
-
var ctrl = new AbortController();
|
|
1474
|
-
setTimeout(function () { return ctrl.abort(); }, ms);
|
|
1475
|
-
return ctrl.signal;
|
|
1476
|
-
});
|
|
1477
|
-
return [4 /*yield*/, retriable(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1478
|
-
var res, e_1;
|
|
1479
|
-
return __generator(this, function (_a) {
|
|
1480
|
-
switch (_a.label) {
|
|
1481
|
-
case 0:
|
|
1482
|
-
res = null;
|
|
1483
|
-
_a.label = 1;
|
|
1484
|
-
case 1:
|
|
1485
|
-
_a.trys.push([1, 3, , 4]);
|
|
1486
|
-
return [4 /*yield*/, this.fetch(url, __assign({ signal: AbortSignal.timeout(this.requestTimeout) }, options))];
|
|
1487
|
-
case 2:
|
|
1488
|
-
res = _a.sent();
|
|
1489
|
-
return [3 /*break*/, 4];
|
|
1490
|
-
case 3:
|
|
1491
|
-
e_1 = _a.sent();
|
|
1492
|
-
// fetch will only throw on network errors or on timeouts
|
|
1493
|
-
throw new PostHogFetchNetworkError(e_1);
|
|
1494
|
-
case 4:
|
|
1495
|
-
if (res.status < 200 || res.status >= 400) {
|
|
1496
|
-
throw new PostHogFetchHttpError(res);
|
|
1497
|
-
}
|
|
1498
|
-
return [2 /*return*/, res];
|
|
1499
|
-
}
|
|
1500
|
-
});
|
|
1501
|
-
}); }, __assign(__assign({}, this._retryOptions), retryOptions))];
|
|
1502
|
-
case 1: return [2 /*return*/, _c.sent()];
|
|
1253
|
+
const done = (err) => {
|
|
1254
|
+
if (err) {
|
|
1255
|
+
this._events.emit('error', err);
|
|
1503
1256
|
}
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
});
|
|
1524
|
-
}))
|
|
1525
|
-
// flush again to make sure we send all events, some of which might've been added
|
|
1526
|
-
// while we were waiting for the pending promises to resolve
|
|
1527
|
-
// For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
|
|
1528
|
-
];
|
|
1529
|
-
case 3:
|
|
1530
|
-
_a.sent();
|
|
1531
|
-
// flush again to make sure we send all events, some of which might've been added
|
|
1532
|
-
// while we were waiting for the pending promises to resolve
|
|
1533
|
-
// For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
|
|
1534
|
-
return [4 /*yield*/, this.flushAsync()];
|
|
1535
|
-
case 4:
|
|
1536
|
-
// flush again to make sure we send all events, some of which might've been added
|
|
1537
|
-
// while we were waiting for the pending promises to resolve
|
|
1538
|
-
// For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
|
|
1539
|
-
_a.sent();
|
|
1540
|
-
return [3 /*break*/, 6];
|
|
1541
|
-
case 5:
|
|
1542
|
-
e_2 = _a.sent();
|
|
1543
|
-
if (!isPostHogFetchError(e_2)) {
|
|
1544
|
-
throw e_2;
|
|
1545
|
-
}
|
|
1546
|
-
console.error('Error while shutting down PostHog', e_2);
|
|
1547
|
-
return [3 /*break*/, 6];
|
|
1548
|
-
case 6: return [2 /*return*/];
|
|
1257
|
+
callback?.(err, messages);
|
|
1258
|
+
this._events.emit('flush', messages);
|
|
1259
|
+
};
|
|
1260
|
+
// Don't set the user agent if we're not on a browser. The latest spec allows
|
|
1261
|
+
// the User-Agent header (see https://fetch.spec.whatwg.org/#terminology-headers
|
|
1262
|
+
// and https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader),
|
|
1263
|
+
// but browsers such as Chrome and Safari have not caught up.
|
|
1264
|
+
this.getCustomUserAgent();
|
|
1265
|
+
const payload = JSON.stringify(data);
|
|
1266
|
+
const url = this.captureMode === 'form'
|
|
1267
|
+
? `${this.host}/e/?ip=1&_=${currentTimestamp()}&v=${this.getLibraryVersion()}`
|
|
1268
|
+
: `${this.host}/batch/`;
|
|
1269
|
+
const fetchOptions = this.captureMode === 'form'
|
|
1270
|
+
? {
|
|
1271
|
+
method: 'POST',
|
|
1272
|
+
mode: 'no-cors',
|
|
1273
|
+
credentials: 'omit',
|
|
1274
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
1275
|
+
body: `data=${encodeURIComponent(LZString.compressToBase64(payload))}&compression=lz64`,
|
|
1549
1276
|
}
|
|
1550
|
-
|
|
1277
|
+
: {
|
|
1278
|
+
method: 'POST',
|
|
1279
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1280
|
+
body: payload,
|
|
1281
|
+
};
|
|
1282
|
+
const requestPromise = this.fetchWithRetry(url, fetchOptions);
|
|
1283
|
+
this.addPendingPromise(requestPromise
|
|
1284
|
+
.then(() => done())
|
|
1285
|
+
.catch((err) => {
|
|
1286
|
+
done(err);
|
|
1287
|
+
}));
|
|
1551
1288
|
});
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1289
|
+
}
|
|
1290
|
+
async fetchWithRetry(url, options, retryOptions, requestTimeout) {
|
|
1291
|
+
var _a;
|
|
1292
|
+
(_a = AbortSignal).timeout ?? (_a.timeout = function timeout(ms) {
|
|
1293
|
+
const ctrl = new AbortController();
|
|
1294
|
+
setTimeout(() => ctrl.abort(), ms);
|
|
1295
|
+
return ctrl.signal;
|
|
1296
|
+
});
|
|
1297
|
+
return await retriable(async () => {
|
|
1298
|
+
let res = null;
|
|
1299
|
+
try {
|
|
1300
|
+
res = await this.fetch(url, {
|
|
1301
|
+
signal: AbortSignal.timeout(requestTimeout ?? this.requestTimeout),
|
|
1302
|
+
...options,
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
catch (e) {
|
|
1306
|
+
// fetch will only throw on network errors or on timeouts
|
|
1307
|
+
throw new PostHogFetchNetworkError(e);
|
|
1308
|
+
}
|
|
1309
|
+
// If we're in no-cors mode, we can't access the response status
|
|
1310
|
+
// We only throw on HTTP errors if we're not in no-cors mode
|
|
1311
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Request/mode#no-cors
|
|
1312
|
+
const isNoCors = options.mode === 'no-cors';
|
|
1313
|
+
if (!isNoCors && (res.status < 200 || res.status >= 400)) {
|
|
1314
|
+
throw new PostHogFetchHttpError(res);
|
|
1315
|
+
}
|
|
1316
|
+
return res;
|
|
1317
|
+
}, { ...this._retryOptions, ...retryOptions });
|
|
1318
|
+
}
|
|
1319
|
+
async shutdownAsync(shutdownTimeoutMs) {
|
|
1320
|
+
await this._initPromise;
|
|
1321
|
+
clearTimeout(this._flushTimer);
|
|
1322
|
+
try {
|
|
1323
|
+
await Promise.all(Object.values(this.pendingPromises).map((x) => x.catch(() => {
|
|
1324
|
+
// ignore errors as we are shutting down and can't deal with them anyways.
|
|
1325
|
+
})));
|
|
1326
|
+
const timeout = shutdownTimeoutMs ?? 30000;
|
|
1327
|
+
const startTimeWithDelay = Date.now() + timeout;
|
|
1328
|
+
while (true) {
|
|
1329
|
+
const queue = this.getPersistedProperty(PostHogPersistedProperty.Queue) || [];
|
|
1330
|
+
if (queue.length === 0) {
|
|
1331
|
+
break;
|
|
1332
|
+
}
|
|
1333
|
+
// flush again to make sure we send all events, some of which might've been added
|
|
1334
|
+
// while we were waiting for the pending promises to resolve
|
|
1335
|
+
// For example, see sendFeatureFlags in posthog-node/src/posthog-node.ts::capture
|
|
1336
|
+
await this.flushAsync();
|
|
1337
|
+
// If we've been waiting for more than the shutdownTimeoutMs, stop it
|
|
1338
|
+
const now = Date.now();
|
|
1339
|
+
if (startTimeWithDelay < now) {
|
|
1340
|
+
break;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
catch (e) {
|
|
1345
|
+
if (!isPostHogFetchError(e)) {
|
|
1346
|
+
throw e;
|
|
1347
|
+
}
|
|
1348
|
+
console.error('Error while shutting down PostHog', e);
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
shutdown(shutdownTimeoutMs) {
|
|
1352
|
+
void this.shutdownAsync(shutdownTimeoutMs);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
class PostHogCore extends PostHogCoreStateless {
|
|
1356
|
+
constructor(apiKey, options) {
|
|
1563
1357
|
// Default for stateful mode is to not disable geoip. Only override if explicitly set
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
if (
|
|
1575
|
-
if (
|
|
1358
|
+
const disableGeoipOption = options?.disableGeoip ?? false;
|
|
1359
|
+
// Default for stateful mode is to timeout at 10s. Only override if explicitly set
|
|
1360
|
+
const featureFlagsRequestTimeoutMs = options?.featureFlagsRequestTimeoutMs ?? 10000; // 10 seconds
|
|
1361
|
+
super(apiKey, { ...options, disableGeoip: disableGeoipOption, featureFlagsRequestTimeoutMs });
|
|
1362
|
+
this.flagCallReported = {};
|
|
1363
|
+
this.sessionProps = {};
|
|
1364
|
+
this.sendFeatureFlagEvent = options?.sendFeatureFlagEvent ?? true;
|
|
1365
|
+
this._sessionExpirationTimeSeconds = options?.sessionExpirationTimeSeconds ?? 1800; // 30 minutes
|
|
1366
|
+
}
|
|
1367
|
+
setupBootstrap(options) {
|
|
1368
|
+
if (options?.bootstrap?.distinctId) {
|
|
1369
|
+
if (options?.bootstrap?.isIdentifiedId) {
|
|
1576
1370
|
this.setPersistedProperty(PostHogPersistedProperty.DistinctId, options.bootstrap.distinctId);
|
|
1577
1371
|
}
|
|
1578
1372
|
else {
|
|
1579
1373
|
this.setPersistedProperty(PostHogPersistedProperty.AnonymousId, options.bootstrap.distinctId);
|
|
1580
1374
|
}
|
|
1581
1375
|
}
|
|
1582
|
-
if (
|
|
1583
|
-
|
|
1584
|
-
.filter(
|
|
1585
|
-
.reduce(
|
|
1586
|
-
var _a, _b;
|
|
1587
|
-
return ((res[key] = ((_b = (_a = options.bootstrap) === null || _a === void 0 ? void 0 : _a.featureFlags) === null || _b === void 0 ? void 0 : _b[key]) || false), res);
|
|
1588
|
-
}, {});
|
|
1376
|
+
if (options?.bootstrap?.featureFlags) {
|
|
1377
|
+
const activeFlags = Object.keys(options.bootstrap?.featureFlags || {})
|
|
1378
|
+
.filter((flag) => !!options.bootstrap?.featureFlags?.[flag])
|
|
1379
|
+
.reduce((res, key) => ((res[key] = options.bootstrap?.featureFlags?.[key] || false), res), {});
|
|
1589
1380
|
this.setKnownFeatureFlags(activeFlags);
|
|
1590
|
-
|
|
1381
|
+
options?.bootstrap.featureFlagPayloads && this.setKnownFeatureFlagPayloads(options?.bootstrap.featureFlagPayloads);
|
|
1591
1382
|
}
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
enumerable: false,
|
|
1605
|
-
configurable: true
|
|
1606
|
-
});
|
|
1607
|
-
PostHogCore.prototype.clearProps = function () {
|
|
1383
|
+
}
|
|
1384
|
+
// NOTE: Props are lazy loaded from localstorage hence the complex getter setter logic
|
|
1385
|
+
get props() {
|
|
1386
|
+
if (!this._props) {
|
|
1387
|
+
this._props = this.getPersistedProperty(PostHogPersistedProperty.Props);
|
|
1388
|
+
}
|
|
1389
|
+
return this._props || {};
|
|
1390
|
+
}
|
|
1391
|
+
set props(val) {
|
|
1392
|
+
this._props = val;
|
|
1393
|
+
}
|
|
1394
|
+
clearProps() {
|
|
1608
1395
|
this.props = undefined;
|
|
1609
1396
|
this.sessionProps = {};
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1397
|
+
}
|
|
1398
|
+
on(event, cb) {
|
|
1612
1399
|
return this._events.on(event, cb);
|
|
1613
|
-
}
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1400
|
+
}
|
|
1401
|
+
reset(propertiesToKeep) {
|
|
1402
|
+
this.wrap(() => {
|
|
1403
|
+
const allPropertiesToKeep = [PostHogPersistedProperty.Queue, ...(propertiesToKeep || [])];
|
|
1404
|
+
// clean up props
|
|
1405
|
+
this.clearProps();
|
|
1406
|
+
for (const key of Object.keys(PostHogPersistedProperty)) {
|
|
1407
|
+
if (!allPropertiesToKeep.includes(PostHogPersistedProperty[key])) {
|
|
1408
|
+
this.setPersistedProperty(PostHogPersistedProperty[key], null);
|
|
1409
|
+
}
|
|
1622
1410
|
}
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1413
|
+
getCommonEventProperties() {
|
|
1414
|
+
const featureFlags = this.getFeatureFlags();
|
|
1415
|
+
const featureVariantProperties = {};
|
|
1628
1416
|
if (featureFlags) {
|
|
1629
|
-
for (
|
|
1630
|
-
|
|
1631
|
-
featureVariantProperties["$feature/".concat(feature)] = variant;
|
|
1417
|
+
for (const [feature, variant] of Object.entries(featureFlags)) {
|
|
1418
|
+
featureVariantProperties[`$feature/${feature}`] = variant;
|
|
1632
1419
|
}
|
|
1633
1420
|
}
|
|
1634
|
-
return
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1421
|
+
return {
|
|
1422
|
+
$active_feature_flags: featureFlags ? Object.keys(featureFlags) : undefined,
|
|
1423
|
+
...featureVariantProperties,
|
|
1424
|
+
...super.getCommonEventProperties(),
|
|
1425
|
+
};
|
|
1426
|
+
}
|
|
1427
|
+
enrichProperties(properties) {
|
|
1428
|
+
return {
|
|
1429
|
+
...this.props,
|
|
1430
|
+
...this.sessionProps,
|
|
1431
|
+
...(properties || {}),
|
|
1432
|
+
...this.getCommonEventProperties(),
|
|
1433
|
+
$session_id: this.getSessionId(),
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* * @returns {string} The stored session ID for the current session. This may be an empty string if the client is not yet fully initialized.
|
|
1438
|
+
*/
|
|
1439
|
+
getSessionId() {
|
|
1440
|
+
if (!this._isInitialized) {
|
|
1441
|
+
return '';
|
|
1442
|
+
}
|
|
1443
|
+
let sessionId = this.getPersistedProperty(PostHogPersistedProperty.SessionId);
|
|
1444
|
+
const sessionTimestamp = this.getPersistedProperty(PostHogPersistedProperty.SessionLastTimestamp) || 0;
|
|
1642
1445
|
if (!sessionId || Date.now() - sessionTimestamp > this._sessionExpirationTimeSeconds * 1000) {
|
|
1643
1446
|
sessionId = uuidv7();
|
|
1644
1447
|
this.setPersistedProperty(PostHogPersistedProperty.SessionId, sessionId);
|
|
1645
1448
|
}
|
|
1646
1449
|
this.setPersistedProperty(PostHogPersistedProperty.SessionLastTimestamp, Date.now());
|
|
1647
1450
|
return sessionId;
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
this.
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1451
|
+
}
|
|
1452
|
+
resetSessionId() {
|
|
1453
|
+
this.wrap(() => {
|
|
1454
|
+
this.setPersistedProperty(PostHogPersistedProperty.SessionId, null);
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
1457
|
+
/**
|
|
1458
|
+
* * @returns {string} The stored anonymous ID. This may be an empty string if the client is not yet fully initialized.
|
|
1459
|
+
*/
|
|
1460
|
+
getAnonymousId() {
|
|
1461
|
+
if (!this._isInitialized) {
|
|
1462
|
+
return '';
|
|
1463
|
+
}
|
|
1464
|
+
let anonId = this.getPersistedProperty(PostHogPersistedProperty.AnonymousId);
|
|
1654
1465
|
if (!anonId) {
|
|
1655
1466
|
anonId = uuidv7();
|
|
1656
1467
|
this.setPersistedProperty(PostHogPersistedProperty.AnonymousId, anonId);
|
|
1657
1468
|
}
|
|
1658
1469
|
return anonId;
|
|
1659
|
-
}
|
|
1660
|
-
|
|
1470
|
+
}
|
|
1471
|
+
/**
|
|
1472
|
+
* * @returns {string} The stored distinct ID. This may be an empty string if the client is not yet fully initialized.
|
|
1473
|
+
*/
|
|
1474
|
+
getDistinctId() {
|
|
1475
|
+
if (!this._isInitialized) {
|
|
1476
|
+
return '';
|
|
1477
|
+
}
|
|
1661
1478
|
return this.getPersistedProperty(PostHogPersistedProperty.DistinctId) || this.getAnonymousId();
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1479
|
+
}
|
|
1480
|
+
async unregister(property) {
|
|
1481
|
+
this.wrap(() => {
|
|
1482
|
+
delete this.props[property];
|
|
1483
|
+
this.setPersistedProperty(PostHogPersistedProperty.Props, this.props);
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
async register(properties) {
|
|
1487
|
+
this.wrap(() => {
|
|
1488
|
+
this.props = {
|
|
1489
|
+
...this.props,
|
|
1490
|
+
...properties,
|
|
1491
|
+
};
|
|
1492
|
+
this.setPersistedProperty(PostHogPersistedProperty.Props, this.props);
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1495
|
+
registerForSession(properties) {
|
|
1496
|
+
this.sessionProps = {
|
|
1497
|
+
...this.sessionProps,
|
|
1498
|
+
...properties,
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
unregisterForSession(property) {
|
|
1675
1502
|
delete this.sessionProps[property];
|
|
1676
|
-
}
|
|
1503
|
+
}
|
|
1677
1504
|
/***
|
|
1678
1505
|
*** TRACKING
|
|
1679
1506
|
***/
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
}
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
this.
|
|
1720
|
-
|
|
1721
|
-
|
|
1507
|
+
identify(distinctId, properties, options) {
|
|
1508
|
+
this.wrap(() => {
|
|
1509
|
+
const previousDistinctId = this.getDistinctId();
|
|
1510
|
+
distinctId = distinctId || previousDistinctId;
|
|
1511
|
+
if (properties?.$groups) {
|
|
1512
|
+
this.groups(properties.$groups);
|
|
1513
|
+
}
|
|
1514
|
+
const allProperties = this.enrichProperties({
|
|
1515
|
+
...properties,
|
|
1516
|
+
$anon_distinct_id: this.getAnonymousId(),
|
|
1517
|
+
$set: properties,
|
|
1518
|
+
});
|
|
1519
|
+
if (distinctId !== previousDistinctId) {
|
|
1520
|
+
// We keep the AnonymousId to be used by decide calls and identify to link the previousId
|
|
1521
|
+
this.setPersistedProperty(PostHogPersistedProperty.AnonymousId, previousDistinctId);
|
|
1522
|
+
this.setPersistedProperty(PostHogPersistedProperty.DistinctId, distinctId);
|
|
1523
|
+
this.reloadFeatureFlags();
|
|
1524
|
+
}
|
|
1525
|
+
super.identifyStateless(distinctId, allProperties, options);
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
capture(event, properties, options) {
|
|
1529
|
+
this.wrap(() => {
|
|
1530
|
+
const distinctId = this.getDistinctId();
|
|
1531
|
+
if (properties?.$groups) {
|
|
1532
|
+
this.groups(properties.$groups);
|
|
1533
|
+
}
|
|
1534
|
+
const allProperties = this.enrichProperties(properties);
|
|
1535
|
+
super.captureStateless(distinctId, event, allProperties, options);
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1538
|
+
alias(alias) {
|
|
1539
|
+
this.wrap(() => {
|
|
1540
|
+
const distinctId = this.getDistinctId();
|
|
1541
|
+
const allProperties = this.enrichProperties({});
|
|
1542
|
+
super.aliasStateless(alias, distinctId, allProperties);
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
autocapture(eventType, elements, properties = {}, options) {
|
|
1546
|
+
this.wrap(() => {
|
|
1547
|
+
const distinctId = this.getDistinctId();
|
|
1548
|
+
const payload = {
|
|
1549
|
+
distinct_id: distinctId,
|
|
1550
|
+
event: '$autocapture',
|
|
1551
|
+
properties: {
|
|
1552
|
+
...this.enrichProperties(properties),
|
|
1553
|
+
$event_type: eventType,
|
|
1554
|
+
$elements: elements,
|
|
1555
|
+
},
|
|
1556
|
+
};
|
|
1557
|
+
this.enqueue('autocapture', payload, options);
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1722
1560
|
/***
|
|
1723
1561
|
*** GROUPS
|
|
1724
1562
|
***/
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1563
|
+
groups(groups) {
|
|
1564
|
+
this.wrap(() => {
|
|
1565
|
+
// Get persisted groups
|
|
1566
|
+
const existingGroups = this.props.$groups || {};
|
|
1567
|
+
this.register({
|
|
1568
|
+
$groups: {
|
|
1569
|
+
...existingGroups,
|
|
1570
|
+
...groups,
|
|
1571
|
+
},
|
|
1572
|
+
});
|
|
1573
|
+
if (Object.keys(groups).find((type) => existingGroups[type] !== groups[type])) {
|
|
1574
|
+
this.reloadFeatureFlags();
|
|
1575
|
+
}
|
|
1730
1576
|
});
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
_super.prototype.groupIdentifyStateless.call(this, groupType, groupKey, groupProperties, options, distinctId, eventProperties);
|
|
1750
|
-
return this;
|
|
1751
|
-
};
|
|
1577
|
+
}
|
|
1578
|
+
group(groupType, groupKey, groupProperties, options) {
|
|
1579
|
+
this.wrap(() => {
|
|
1580
|
+
this.groups({
|
|
1581
|
+
[groupType]: groupKey,
|
|
1582
|
+
});
|
|
1583
|
+
if (groupProperties) {
|
|
1584
|
+
this.groupIdentify(groupType, groupKey, groupProperties, options);
|
|
1585
|
+
}
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1588
|
+
groupIdentify(groupType, groupKey, groupProperties, options) {
|
|
1589
|
+
this.wrap(() => {
|
|
1590
|
+
const distinctId = this.getDistinctId();
|
|
1591
|
+
const eventProperties = this.enrichProperties({});
|
|
1592
|
+
super.groupIdentifyStateless(groupType, groupKey, groupProperties, options, distinctId, eventProperties);
|
|
1593
|
+
});
|
|
1594
|
+
}
|
|
1752
1595
|
/***
|
|
1753
1596
|
* PROPERTIES
|
|
1754
1597
|
***/
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1598
|
+
setPersonPropertiesForFlags(properties) {
|
|
1599
|
+
this.wrap(() => {
|
|
1600
|
+
// Get persisted person properties
|
|
1601
|
+
const existingProperties = this.getPersistedProperty(PostHogPersistedProperty.PersonProperties) || {};
|
|
1602
|
+
this.setPersistedProperty(PostHogPersistedProperty.PersonProperties, {
|
|
1603
|
+
...existingProperties,
|
|
1604
|
+
...properties,
|
|
1605
|
+
});
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1608
|
+
resetPersonPropertiesForFlags() {
|
|
1609
|
+
this.wrap(() => {
|
|
1610
|
+
this.setPersistedProperty(PostHogPersistedProperty.PersonProperties, {});
|
|
1611
|
+
});
|
|
1612
|
+
}
|
|
1764
1613
|
/** @deprecated - Renamed to setPersonPropertiesForFlags */
|
|
1765
|
-
|
|
1614
|
+
personProperties(properties) {
|
|
1766
1615
|
return this.setPersonPropertiesForFlags(properties);
|
|
1767
|
-
}
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1616
|
+
}
|
|
1617
|
+
setGroupPropertiesForFlags(properties) {
|
|
1618
|
+
this.wrap(() => {
|
|
1619
|
+
// Get persisted group properties
|
|
1620
|
+
const existingProperties = this.getPersistedProperty(PostHogPersistedProperty.GroupProperties) ||
|
|
1621
|
+
{};
|
|
1622
|
+
if (Object.keys(existingProperties).length !== 0) {
|
|
1623
|
+
Object.keys(existingProperties).forEach((groupType) => {
|
|
1624
|
+
existingProperties[groupType] = {
|
|
1625
|
+
...existingProperties[groupType],
|
|
1626
|
+
...properties[groupType],
|
|
1627
|
+
};
|
|
1628
|
+
delete properties[groupType];
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1631
|
+
this.setPersistedProperty(PostHogPersistedProperty.GroupProperties, {
|
|
1632
|
+
...existingProperties,
|
|
1633
|
+
...properties,
|
|
1775
1634
|
});
|
|
1776
|
-
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
}
|
|
1635
|
+
});
|
|
1636
|
+
}
|
|
1637
|
+
resetGroupPropertiesForFlags() {
|
|
1638
|
+
this.wrap(() => {
|
|
1639
|
+
this.setPersistedProperty(PostHogPersistedProperty.GroupProperties, {});
|
|
1640
|
+
});
|
|
1641
|
+
}
|
|
1783
1642
|
/** @deprecated - Renamed to setGroupPropertiesForFlags */
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1643
|
+
groupProperties(properties) {
|
|
1644
|
+
this.wrap(() => {
|
|
1645
|
+
this.setGroupPropertiesForFlags(properties);
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1787
1648
|
/***
|
|
1788
1649
|
*** FEATURE FLAGS
|
|
1789
1650
|
***/
|
|
1790
|
-
|
|
1791
|
-
|
|
1651
|
+
async decideAsync(sendAnonDistinctId = true) {
|
|
1652
|
+
await this._initPromise;
|
|
1792
1653
|
if (this._decideResponsePromise) {
|
|
1793
1654
|
return this._decideResponsePromise;
|
|
1794
1655
|
}
|
|
1795
1656
|
return this._decideAsync(sendAnonDistinctId);
|
|
1796
|
-
}
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
if (res
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
var currentFlagPayloads = _this.getPersistedProperty(PostHogPersistedProperty.FeatureFlagPayloads);
|
|
1819
|
-
newFeatureFlags = __assign(__assign({}, currentFlags), res.featureFlags);
|
|
1820
|
-
newFeatureFlagPayloads = __assign(__assign({}, currentFlagPayloads), res.featureFlagPayloads);
|
|
1821
|
-
}
|
|
1822
|
-
_this.setKnownFeatureFlags(newFeatureFlags);
|
|
1823
|
-
_this.setKnownFeatureFlagPayloads(newFeatureFlagPayloads);
|
|
1657
|
+
}
|
|
1658
|
+
async _decideAsync(sendAnonDistinctId = true) {
|
|
1659
|
+
this._decideResponsePromise = this._initPromise
|
|
1660
|
+
.then(() => {
|
|
1661
|
+
const distinctId = this.getDistinctId();
|
|
1662
|
+
const groups = this.props.$groups || {};
|
|
1663
|
+
const personProperties = this.getPersistedProperty(PostHogPersistedProperty.PersonProperties) || {};
|
|
1664
|
+
const groupProperties = this.getPersistedProperty(PostHogPersistedProperty.GroupProperties) ||
|
|
1665
|
+
{};
|
|
1666
|
+
const extraProperties = {
|
|
1667
|
+
$anon_distinct_id: sendAnonDistinctId ? this.getAnonymousId() : undefined,
|
|
1668
|
+
};
|
|
1669
|
+
return super.getDecide(distinctId, groups, personProperties, groupProperties, extraProperties).then((res) => {
|
|
1670
|
+
if (res?.featureFlags) {
|
|
1671
|
+
let newFeatureFlags = res.featureFlags;
|
|
1672
|
+
let newFeatureFlagPayloads = res.featureFlagPayloads;
|
|
1673
|
+
if (res.errorsWhileComputingFlags) {
|
|
1674
|
+
// if not all flags were computed, we upsert flags instead of replacing them
|
|
1675
|
+
const currentFlags = this.getPersistedProperty(PostHogPersistedProperty.FeatureFlags);
|
|
1676
|
+
const currentFlagPayloads = this.getPersistedProperty(PostHogPersistedProperty.FeatureFlagPayloads);
|
|
1677
|
+
newFeatureFlags = { ...currentFlags, ...res.featureFlags };
|
|
1678
|
+
newFeatureFlagPayloads = { ...currentFlagPayloads, ...res.featureFlagPayloads };
|
|
1824
1679
|
}
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
});
|
|
1830
|
-
return [2 /*return*/, this._decideResponsePromise];
|
|
1680
|
+
this.setKnownFeatureFlags(newFeatureFlags);
|
|
1681
|
+
this.setKnownFeatureFlagPayloads(newFeatureFlagPayloads);
|
|
1682
|
+
}
|
|
1683
|
+
return res;
|
|
1831
1684
|
});
|
|
1685
|
+
})
|
|
1686
|
+
.finally(() => {
|
|
1687
|
+
this._decideResponsePromise = undefined;
|
|
1832
1688
|
});
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
this.
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
|
|
1689
|
+
return this._decideResponsePromise;
|
|
1690
|
+
}
|
|
1691
|
+
setKnownFeatureFlags(featureFlags) {
|
|
1692
|
+
this.wrap(() => {
|
|
1693
|
+
this.setPersistedProperty(PostHogPersistedProperty.FeatureFlags, featureFlags);
|
|
1694
|
+
this._events.emit('featureflags', featureFlags);
|
|
1695
|
+
});
|
|
1696
|
+
}
|
|
1697
|
+
setKnownFeatureFlagPayloads(featureFlagPayloads) {
|
|
1698
|
+
this.wrap(() => {
|
|
1699
|
+
this.setPersistedProperty(PostHogPersistedProperty.FeatureFlagPayloads, featureFlagPayloads);
|
|
1700
|
+
});
|
|
1701
|
+
}
|
|
1702
|
+
getFeatureFlag(key) {
|
|
1703
|
+
const featureFlags = this.getFeatureFlags();
|
|
1843
1704
|
if (!featureFlags) {
|
|
1844
1705
|
// If we haven't loaded flags yet, or errored out, we respond with undefined
|
|
1845
1706
|
return undefined;
|
|
1846
1707
|
}
|
|
1847
|
-
|
|
1708
|
+
let response = featureFlags[key];
|
|
1848
1709
|
// `/decide` v3 returns all flags
|
|
1849
1710
|
if (response === undefined) {
|
|
1850
1711
|
// For cases where the flag is unknown, return false
|
|
@@ -1859,38 +1720,36 @@ var PostHogCore = /** @class */ (function (_super) {
|
|
|
1859
1720
|
}
|
|
1860
1721
|
// If we have flags we either return the value (true or string) or false
|
|
1861
1722
|
return response;
|
|
1862
|
-
}
|
|
1863
|
-
|
|
1864
|
-
|
|
1723
|
+
}
|
|
1724
|
+
getFeatureFlagPayload(key) {
|
|
1725
|
+
const payloads = this.getFeatureFlagPayloads();
|
|
1865
1726
|
if (!payloads) {
|
|
1866
1727
|
return undefined;
|
|
1867
1728
|
}
|
|
1868
|
-
|
|
1729
|
+
const response = payloads[key];
|
|
1869
1730
|
// Undefined means a loading or missing data issue. Null means evaluation happened and there was no match
|
|
1870
1731
|
if (response === undefined) {
|
|
1871
1732
|
return null;
|
|
1872
1733
|
}
|
|
1873
1734
|
return this._parsePayload(response);
|
|
1874
|
-
}
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
var payloads = this.getPersistedProperty(PostHogPersistedProperty.FeatureFlagPayloads);
|
|
1735
|
+
}
|
|
1736
|
+
getFeatureFlagPayloads() {
|
|
1737
|
+
const payloads = this.getPersistedProperty(PostHogPersistedProperty.FeatureFlagPayloads);
|
|
1878
1738
|
if (payloads) {
|
|
1879
|
-
return Object.fromEntries(Object.entries(payloads).map(
|
|
1880
|
-
var k = _a[0], v = _a[1];
|
|
1881
|
-
return [k, _this._parsePayload(v)];
|
|
1882
|
-
}));
|
|
1739
|
+
return Object.fromEntries(Object.entries(payloads).map(([k, v]) => [k, this._parsePayload(v)]));
|
|
1883
1740
|
}
|
|
1884
1741
|
return payloads;
|
|
1885
|
-
}
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1742
|
+
}
|
|
1743
|
+
getFeatureFlags() {
|
|
1744
|
+
// NOTE: We don't check for _initPromise here as the function is designed to be
|
|
1745
|
+
// callable before the state being loaded anyways
|
|
1746
|
+
let flags = this.getPersistedProperty(PostHogPersistedProperty.FeatureFlags);
|
|
1747
|
+
const overriddenFlags = this.getPersistedProperty(PostHogPersistedProperty.OverrideFeatureFlags);
|
|
1889
1748
|
if (!overriddenFlags) {
|
|
1890
1749
|
return flags;
|
|
1891
1750
|
}
|
|
1892
1751
|
flags = flags || {};
|
|
1893
|
-
for (
|
|
1752
|
+
for (const key in overriddenFlags) {
|
|
1894
1753
|
if (!overriddenFlags[key]) {
|
|
1895
1754
|
delete flags[key];
|
|
1896
1755
|
}
|
|
@@ -1899,90 +1758,72 @@ var PostHogCore = /** @class */ (function (_super) {
|
|
|
1899
1758
|
}
|
|
1900
1759
|
}
|
|
1901
1760
|
return flags;
|
|
1902
|
-
}
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1761
|
+
}
|
|
1762
|
+
getFeatureFlagsAndPayloads() {
|
|
1763
|
+
const flags = this.getFeatureFlags();
|
|
1764
|
+
const payloads = this.getFeatureFlagPayloads();
|
|
1906
1765
|
return {
|
|
1907
|
-
flags
|
|
1908
|
-
payloads
|
|
1766
|
+
flags,
|
|
1767
|
+
payloads,
|
|
1909
1768
|
};
|
|
1910
|
-
}
|
|
1911
|
-
|
|
1912
|
-
|
|
1769
|
+
}
|
|
1770
|
+
isFeatureEnabled(key) {
|
|
1771
|
+
const response = this.getFeatureFlag(key);
|
|
1913
1772
|
if (response === undefined) {
|
|
1914
1773
|
return undefined;
|
|
1915
1774
|
}
|
|
1916
1775
|
return !!response;
|
|
1917
|
-
}
|
|
1776
|
+
}
|
|
1918
1777
|
// Used when we want to trigger the reload but we don't care about the result
|
|
1919
|
-
|
|
1778
|
+
reloadFeatureFlags(cb) {
|
|
1920
1779
|
this.decideAsync()
|
|
1921
|
-
.then(
|
|
1922
|
-
cb
|
|
1780
|
+
.then((res) => {
|
|
1781
|
+
cb?.(undefined, res?.featureFlags);
|
|
1923
1782
|
})
|
|
1924
|
-
.catch(
|
|
1925
|
-
cb
|
|
1783
|
+
.catch((e) => {
|
|
1784
|
+
cb?.(e, undefined);
|
|
1926
1785
|
if (!cb) {
|
|
1927
1786
|
console.log('[PostHog] Error reloading feature flags', e);
|
|
1928
1787
|
}
|
|
1929
1788
|
});
|
|
1930
|
-
}
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
});
|
|
1789
|
+
}
|
|
1790
|
+
async reloadFeatureFlagsAsync(sendAnonDistinctId = true) {
|
|
1791
|
+
return (await this.decideAsync(sendAnonDistinctId))?.featureFlags;
|
|
1792
|
+
}
|
|
1793
|
+
onFeatureFlags(cb) {
|
|
1794
|
+
return this.on('featureflags', async () => {
|
|
1795
|
+
const flags = this.getFeatureFlags();
|
|
1796
|
+
if (flags) {
|
|
1797
|
+
cb(flags);
|
|
1798
|
+
}
|
|
1941
1799
|
});
|
|
1942
|
-
}
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
return __generator(this, function (_a) {
|
|
1961
|
-
flagResponse = this.getFeatureFlag(key);
|
|
1962
|
-
if (flagResponse !== undefined) {
|
|
1963
|
-
cb(flagResponse);
|
|
1964
|
-
}
|
|
1965
|
-
return [2 /*return*/];
|
|
1966
|
-
});
|
|
1967
|
-
}); });
|
|
1968
|
-
};
|
|
1969
|
-
PostHogCore.prototype.overrideFeatureFlag = function (flags) {
|
|
1970
|
-
if (flags === null) {
|
|
1971
|
-
return this.setPersistedProperty(PostHogPersistedProperty.OverrideFeatureFlags, null);
|
|
1972
|
-
}
|
|
1973
|
-
return this.setPersistedProperty(PostHogPersistedProperty.OverrideFeatureFlags, flags);
|
|
1974
|
-
};
|
|
1975
|
-
return PostHogCore;
|
|
1976
|
-
}(PostHogCoreStateless));
|
|
1800
|
+
}
|
|
1801
|
+
onFeatureFlag(key, cb) {
|
|
1802
|
+
return this.on('featureflags', async () => {
|
|
1803
|
+
const flagResponse = this.getFeatureFlag(key);
|
|
1804
|
+
if (flagResponse !== undefined) {
|
|
1805
|
+
cb(flagResponse);
|
|
1806
|
+
}
|
|
1807
|
+
});
|
|
1808
|
+
}
|
|
1809
|
+
async overrideFeatureFlag(flags) {
|
|
1810
|
+
this.wrap(() => {
|
|
1811
|
+
if (flags === null) {
|
|
1812
|
+
return this.setPersistedProperty(PostHogPersistedProperty.OverrideFeatureFlags, null);
|
|
1813
|
+
}
|
|
1814
|
+
return this.setPersistedProperty(PostHogPersistedProperty.OverrideFeatureFlags, flags);
|
|
1815
|
+
});
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1977
1818
|
|
|
1978
|
-
var version = "
|
|
1819
|
+
var version = "3.0.0-beta.1";
|
|
1979
1820
|
|
|
1980
1821
|
function getContext(window) {
|
|
1981
|
-
|
|
1822
|
+
let context = {};
|
|
1982
1823
|
|
|
1983
1824
|
if (window.navigator) {
|
|
1984
|
-
|
|
1985
|
-
context =
|
|
1825
|
+
const userAgent = window.navigator.userAgent;
|
|
1826
|
+
context = { ...context,
|
|
1986
1827
|
$os: os(window),
|
|
1987
1828
|
$browser: browser(userAgent, window.navigator.vendor, !!window.opera),
|
|
1988
1829
|
$referrer: window.document.referrer,
|
|
@@ -1995,15 +1836,16 @@ function getContext(window) {
|
|
|
1995
1836
|
$screen_height: window.screen.height,
|
|
1996
1837
|
$screen_width: window.screen.width,
|
|
1997
1838
|
$screen_dpr: window.devicePixelRatio
|
|
1998
|
-
}
|
|
1839
|
+
};
|
|
1999
1840
|
}
|
|
2000
1841
|
|
|
2001
|
-
context =
|
|
1842
|
+
context = { ...context,
|
|
2002
1843
|
$lib: 'js',
|
|
2003
1844
|
$lib_version: version,
|
|
2004
1845
|
$insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),
|
|
2005
|
-
$time: currentTimestamp() / 1000
|
|
2006
|
-
|
|
1846
|
+
$time: currentTimestamp() / 1000 // epoch time in seconds
|
|
1847
|
+
|
|
1848
|
+
};
|
|
2007
1849
|
return context; // TODO: strip empty props?
|
|
2008
1850
|
}
|
|
2009
1851
|
|
|
@@ -2061,7 +1903,7 @@ function browser(userAgent, vendor, opera) {
|
|
|
2061
1903
|
}
|
|
2062
1904
|
|
|
2063
1905
|
function browserVersion(userAgent, vendor, opera) {
|
|
2064
|
-
|
|
1906
|
+
const regexList = {
|
|
2065
1907
|
'Internet Explorer Mobile': /rv:(\d+(\.\d+)?)/,
|
|
2066
1908
|
'Microsoft Edge': /Edge?\/(\d+(\.\d+)?)/,
|
|
2067
1909
|
Chrome: /Chrome\/(\d+(\.\d+)?)/,
|
|
@@ -2079,14 +1921,14 @@ function browserVersion(userAgent, vendor, opera) {
|
|
|
2079
1921
|
'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/,
|
|
2080
1922
|
Mozilla: /rv:(\d+(\.\d+)?)/
|
|
2081
1923
|
};
|
|
2082
|
-
|
|
2083
|
-
|
|
1924
|
+
const browserString = browser(userAgent, vendor, opera);
|
|
1925
|
+
const regex = regexList[browserString] || undefined;
|
|
2084
1926
|
|
|
2085
1927
|
if (regex === undefined) {
|
|
2086
1928
|
return null;
|
|
2087
1929
|
}
|
|
2088
1930
|
|
|
2089
|
-
|
|
1931
|
+
const matches = userAgent.match(regex);
|
|
2090
1932
|
|
|
2091
1933
|
if (!matches) {
|
|
2092
1934
|
return null;
|
|
@@ -2096,7 +1938,7 @@ function browserVersion(userAgent, vendor, opera) {
|
|
|
2096
1938
|
}
|
|
2097
1939
|
|
|
2098
1940
|
function os(window) {
|
|
2099
|
-
|
|
1941
|
+
const a = window.navigator.userAgent;
|
|
2100
1942
|
|
|
2101
1943
|
if (/Windows/i.test(a)) {
|
|
2102
1944
|
if (/Phone/.test(a) || /WPDesktop/.test(a)) {
|
|
@@ -2140,7 +1982,7 @@ function device(userAgent) {
|
|
|
2140
1982
|
}
|
|
2141
1983
|
|
|
2142
1984
|
function referringDomain(referrer) {
|
|
2143
|
-
|
|
1985
|
+
const split = referrer.split('/');
|
|
2144
1986
|
|
|
2145
1987
|
if (split.length >= 3) {
|
|
2146
1988
|
return split[2];
|
|
@@ -2150,14 +1992,14 @@ function referringDomain(referrer) {
|
|
|
2150
1992
|
}
|
|
2151
1993
|
|
|
2152
1994
|
// Methods partially borrowed from quirksmode.org/js/cookies.html
|
|
2153
|
-
|
|
2154
|
-
getItem
|
|
1995
|
+
const cookieStore = {
|
|
1996
|
+
getItem(key) {
|
|
2155
1997
|
try {
|
|
2156
|
-
|
|
2157
|
-
|
|
1998
|
+
const nameEQ = key + '=';
|
|
1999
|
+
const ca = document.cookie.split(';');
|
|
2158
2000
|
|
|
2159
|
-
for (
|
|
2160
|
-
|
|
2001
|
+
for (let i = 0; i < ca.length; i++) {
|
|
2002
|
+
let c = ca[i];
|
|
2161
2003
|
|
|
2162
2004
|
while (c.charAt(0) == ' ') {
|
|
2163
2005
|
c = c.substring(1, c.length);
|
|
@@ -2171,33 +2013,37 @@ var cookieStore = {
|
|
|
2171
2013
|
|
|
2172
2014
|
return null;
|
|
2173
2015
|
},
|
|
2174
|
-
|
|
2016
|
+
|
|
2017
|
+
setItem(key, value) {
|
|
2175
2018
|
try {
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2019
|
+
const cdomain = '',
|
|
2020
|
+
expires = '',
|
|
2021
|
+
secure = '';
|
|
2022
|
+
const new_cookie_val = key + '=' + encodeURIComponent(value) + expires + '; path=/' + cdomain + secure;
|
|
2180
2023
|
document.cookie = new_cookie_val;
|
|
2181
2024
|
} catch (err) {
|
|
2182
2025
|
return;
|
|
2183
2026
|
}
|
|
2184
2027
|
},
|
|
2185
|
-
|
|
2028
|
+
|
|
2029
|
+
removeItem(name) {
|
|
2186
2030
|
try {
|
|
2187
2031
|
cookieStore.setItem(name, '');
|
|
2188
2032
|
} catch (err) {
|
|
2189
2033
|
return;
|
|
2190
2034
|
}
|
|
2191
2035
|
},
|
|
2192
|
-
|
|
2036
|
+
|
|
2037
|
+
clear() {
|
|
2193
2038
|
document.cookie = '';
|
|
2194
2039
|
},
|
|
2195
|
-
getAllKeys: function () {
|
|
2196
|
-
var ca = document.cookie.split(';');
|
|
2197
|
-
var keys = [];
|
|
2198
2040
|
|
|
2199
|
-
|
|
2200
|
-
|
|
2041
|
+
getAllKeys() {
|
|
2042
|
+
const ca = document.cookie.split(';');
|
|
2043
|
+
const keys = [];
|
|
2044
|
+
|
|
2045
|
+
for (let i = 0; i < ca.length; i++) {
|
|
2046
|
+
let c = ca[i];
|
|
2201
2047
|
|
|
2202
2048
|
while (c.charAt(0) == ' ') {
|
|
2203
2049
|
c = c.substring(1, c.length);
|
|
@@ -2208,45 +2054,47 @@ var cookieStore = {
|
|
|
2208
2054
|
|
|
2209
2055
|
return keys;
|
|
2210
2056
|
}
|
|
2057
|
+
|
|
2211
2058
|
};
|
|
2212
2059
|
|
|
2213
|
-
|
|
2060
|
+
const createStorageLike = store => {
|
|
2214
2061
|
return {
|
|
2215
|
-
getItem
|
|
2062
|
+
getItem(key) {
|
|
2216
2063
|
return store.getItem(key);
|
|
2217
2064
|
},
|
|
2218
|
-
|
|
2065
|
+
|
|
2066
|
+
setItem(key, value) {
|
|
2219
2067
|
store.setItem(key, value);
|
|
2220
2068
|
},
|
|
2221
|
-
|
|
2069
|
+
|
|
2070
|
+
removeItem(key) {
|
|
2222
2071
|
store.removeItem(key);
|
|
2223
2072
|
},
|
|
2224
|
-
|
|
2073
|
+
|
|
2074
|
+
clear() {
|
|
2225
2075
|
store.clear();
|
|
2226
2076
|
},
|
|
2227
|
-
getAllKeys: function () {
|
|
2228
|
-
var keys = [];
|
|
2229
2077
|
|
|
2230
|
-
|
|
2078
|
+
getAllKeys() {
|
|
2079
|
+
const keys = [];
|
|
2080
|
+
|
|
2081
|
+
for (const key in localStorage) {
|
|
2231
2082
|
keys.push(key);
|
|
2232
2083
|
}
|
|
2233
2084
|
|
|
2234
2085
|
return keys;
|
|
2235
2086
|
}
|
|
2087
|
+
|
|
2236
2088
|
};
|
|
2237
2089
|
};
|
|
2238
2090
|
|
|
2239
|
-
|
|
2240
|
-
if (key === void 0) {
|
|
2241
|
-
key = '__mplssupport__';
|
|
2242
|
-
}
|
|
2243
|
-
|
|
2091
|
+
const checkStoreIsSupported = (storage, key = '__mplssupport__') => {
|
|
2244
2092
|
if (!window) {
|
|
2245
2093
|
return false;
|
|
2246
2094
|
}
|
|
2247
2095
|
|
|
2248
2096
|
try {
|
|
2249
|
-
|
|
2097
|
+
const val = 'xyz';
|
|
2250
2098
|
storage.setItem(key, val);
|
|
2251
2099
|
|
|
2252
2100
|
if (storage.getItem(key) !== val) {
|
|
@@ -2260,49 +2108,54 @@ var checkStoreIsSupported = function (storage, key) {
|
|
|
2260
2108
|
}
|
|
2261
2109
|
};
|
|
2262
2110
|
|
|
2263
|
-
|
|
2264
|
-
|
|
2111
|
+
let localStore = undefined;
|
|
2112
|
+
let sessionStore = undefined;
|
|
2265
2113
|
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
getItem
|
|
2114
|
+
const createMemoryStorage = () => {
|
|
2115
|
+
const _cache = {};
|
|
2116
|
+
const store = {
|
|
2117
|
+
getItem(key) {
|
|
2270
2118
|
return _cache[key];
|
|
2271
2119
|
},
|
|
2272
|
-
|
|
2120
|
+
|
|
2121
|
+
setItem(key, value) {
|
|
2273
2122
|
_cache[key] = value !== null ? value : undefined;
|
|
2274
2123
|
},
|
|
2275
|
-
|
|
2124
|
+
|
|
2125
|
+
removeItem(key) {
|
|
2276
2126
|
delete _cache[key];
|
|
2277
2127
|
},
|
|
2278
|
-
|
|
2279
|
-
|
|
2128
|
+
|
|
2129
|
+
clear() {
|
|
2130
|
+
for (const key in _cache) {
|
|
2280
2131
|
delete _cache[key];
|
|
2281
2132
|
}
|
|
2282
2133
|
},
|
|
2283
|
-
getAllKeys: function () {
|
|
2284
|
-
var keys = [];
|
|
2285
2134
|
|
|
2286
|
-
|
|
2135
|
+
getAllKeys() {
|
|
2136
|
+
const keys = [];
|
|
2137
|
+
|
|
2138
|
+
for (const key in _cache) {
|
|
2287
2139
|
keys.push(key);
|
|
2288
2140
|
}
|
|
2289
2141
|
|
|
2290
2142
|
return keys;
|
|
2291
2143
|
}
|
|
2144
|
+
|
|
2292
2145
|
};
|
|
2293
2146
|
return store;
|
|
2294
2147
|
};
|
|
2295
2148
|
|
|
2296
|
-
|
|
2149
|
+
const getStorage = (type, window) => {
|
|
2297
2150
|
if (window) {
|
|
2298
2151
|
if (!localStorage) {
|
|
2299
|
-
|
|
2152
|
+
const _localStore = createStorageLike(window.localStorage);
|
|
2300
2153
|
|
|
2301
2154
|
localStore = checkStoreIsSupported(_localStore) ? _localStore : undefined;
|
|
2302
2155
|
}
|
|
2303
2156
|
|
|
2304
2157
|
if (!sessionStore) {
|
|
2305
|
-
|
|
2158
|
+
const _sessionStore = createStorageLike(window.sessionStorage);
|
|
2306
2159
|
|
|
2307
2160
|
sessionStore = checkStoreIsSupported(_sessionStore) ? _sessionStore : undefined;
|
|
2308
2161
|
}
|
|
@@ -2326,36 +2179,28 @@ var getStorage = function (type, window) {
|
|
|
2326
2179
|
}
|
|
2327
2180
|
};
|
|
2328
2181
|
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
__extends(PostHog, _super);
|
|
2333
|
-
|
|
2334
|
-
function PostHog(apiKey, options) {
|
|
2335
|
-
var _this = _super.call(this, apiKey, options) || this; // posthog-js stores options in one object on
|
|
2336
|
-
|
|
2182
|
+
class PostHog extends PostHogCore {
|
|
2183
|
+
constructor(apiKey, options) {
|
|
2184
|
+
super(apiKey, options); // posthog-js stores options in one object on
|
|
2337
2185
|
|
|
2338
|
-
|
|
2339
|
-
|
|
2186
|
+
this._storageKey = options?.persistence_name ? `ph_${options.persistence_name}` : `ph_${apiKey}_posthog`;
|
|
2187
|
+
this._storage = getStorage(options?.persistence || 'localStorage', window);
|
|
2188
|
+
this.setupBootstrap(options);
|
|
2340
2189
|
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
if ((options === null || options === void 0 ? void 0 : options.preloadFeatureFlags) !== false) {
|
|
2344
|
-
_this.reloadFeatureFlags();
|
|
2190
|
+
if (options?.preloadFeatureFlags !== false) {
|
|
2191
|
+
this.reloadFeatureFlags();
|
|
2345
2192
|
}
|
|
2346
|
-
|
|
2347
|
-
return _this;
|
|
2348
2193
|
}
|
|
2349
2194
|
|
|
2350
|
-
|
|
2195
|
+
getPersistedProperty(key) {
|
|
2351
2196
|
if (!this._storageCache) {
|
|
2352
2197
|
this._storageCache = JSON.parse(this._storage.getItem(this._storageKey) || '{}') || {};
|
|
2353
2198
|
}
|
|
2354
2199
|
|
|
2355
2200
|
return this._storageCache[key];
|
|
2356
|
-
}
|
|
2201
|
+
}
|
|
2357
2202
|
|
|
2358
|
-
|
|
2203
|
+
setPersistedProperty(key, value) {
|
|
2359
2204
|
if (!this._storageCache) {
|
|
2360
2205
|
this._storageCache = JSON.parse(this._storage.getItem(this._storageKey) || '{}') || {};
|
|
2361
2206
|
}
|
|
@@ -2367,30 +2212,31 @@ function (_super) {
|
|
|
2367
2212
|
}
|
|
2368
2213
|
|
|
2369
2214
|
this._storage.setItem(this._storageKey, JSON.stringify(this._storageCache));
|
|
2370
|
-
}
|
|
2215
|
+
}
|
|
2371
2216
|
|
|
2372
|
-
|
|
2217
|
+
fetch(url, options) {
|
|
2373
2218
|
return window.fetch(url, options);
|
|
2374
|
-
}
|
|
2219
|
+
}
|
|
2375
2220
|
|
|
2376
|
-
|
|
2221
|
+
getLibraryId() {
|
|
2377
2222
|
return 'posthog-js-lite';
|
|
2378
|
-
}
|
|
2223
|
+
}
|
|
2379
2224
|
|
|
2380
|
-
|
|
2225
|
+
getLibraryVersion() {
|
|
2381
2226
|
return version;
|
|
2382
|
-
}
|
|
2227
|
+
}
|
|
2383
2228
|
|
|
2384
|
-
|
|
2229
|
+
getCustomUserAgent() {
|
|
2385
2230
|
return;
|
|
2386
|
-
}
|
|
2231
|
+
}
|
|
2387
2232
|
|
|
2388
|
-
|
|
2389
|
-
return
|
|
2390
|
-
|
|
2233
|
+
getCommonEventProperties() {
|
|
2234
|
+
return { ...super.getCommonEventProperties(),
|
|
2235
|
+
...getContext(window)
|
|
2236
|
+
};
|
|
2237
|
+
}
|
|
2391
2238
|
|
|
2392
|
-
|
|
2393
|
-
}(PostHogCore);
|
|
2239
|
+
}
|
|
2394
2240
|
|
|
2395
2241
|
exports.PostHog = PostHog;
|
|
2396
2242
|
exports["default"] = PostHog;
|