@reservamos/browser-analytics 1.1.8-alpha.1 → 1.1.8-alpha.3
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 +19 -2
- package/README.md +32 -4
- package/dist/browser-analytics.cjs +2 -2
- package/dist/browser-analytics.cjs.map +1 -1
- package/dist/browser-analytics.d.ts +23 -10
- package/dist/browser-analytics.esm.js +466 -154
- package/dist/browser-analytics.esm.js.map +1 -1
- package/dist/browser-analytics.iife.js +2 -2
- package/dist/browser-analytics.iife.js.map +1 -1
- package/package.json +2 -2
- package/src/events/identify/identify.recovery.test.ts +367 -0
- package/src/events/identify/identify.robustness.test.ts +112 -13
- package/src/events/identify/identify.ts +72 -35
- package/src/events/passengersCreated/passengersCreatedSchema.test.ts +142 -0
- package/src/events/passengersCreated/passengersCreatedSchema.ts +7 -1
- package/src/events/purchaseConfirmation/purchaseConfirmation.integration.test.ts +49 -0
- package/src/events/purchaseConfirmation/purchaseConfirmation.test.ts +17 -0
- package/src/events/purchaseConfirmation/purchaseConfirmationSchema.ts +2 -0
- package/src/index.ts +1 -0
- package/src/init.ts +10 -1
- package/src/profiles/createAnonymousProfile/createAnonymousProfile.ts +18 -2
- package/src/services/botDetectionRelay.test.ts +3 -2
- package/src/services/fingerprint.test.ts +172 -0
- package/src/services/fingerprint.ts +106 -5
- package/src/services/fingerprint.wait.integration.test.ts +129 -0
- package/src/services/mixpanel.batch.test.ts +108 -0
- package/src/services/mixpanel.test.ts +77 -73
- package/src/services/mixpanel.ts +45 -18
- package/src/services/profileEnrichment.ts +258 -0
- package/src/track.storage.test.ts +27 -12
|
@@ -4173,7 +4173,8 @@ function r$3({ apiName: r2, defaultApiVersion: i }) {
|
|
|
4173
4173
|
method: "POST",
|
|
4174
4174
|
body: JSON.stringify(p3),
|
|
4175
4175
|
headers: _2,
|
|
4176
|
-
...(f3 == null ? void 0 : f3.signal) && { signal: f3.signal }
|
|
4176
|
+
...(f3 == null ? void 0 : f3.signal) && { signal: f3.signal },
|
|
4177
|
+
...(f3 == null ? void 0 : f3.keepalive) !== void 0 && { keepalive: f3.keepalive }
|
|
4177
4178
|
});
|
|
4178
4179
|
return f3 ? y2 : await y2.json();
|
|
4179
4180
|
}
|
|
@@ -4269,7 +4270,8 @@ async function a$3({ requestId: a2, visitorId: o2, distinctId: s2, purchaseToken
|
|
|
4269
4270
|
responseType: "response",
|
|
4270
4271
|
apiPrefix: "api",
|
|
4271
4272
|
omitHeaders: ["Origin"],
|
|
4272
|
-
signal: u2.signal
|
|
4273
|
+
signal: u2.signal,
|
|
4274
|
+
keepalive: true
|
|
4273
4275
|
});
|
|
4274
4276
|
return l2 && r$2(l2, {
|
|
4275
4277
|
httpStatus: e3.status,
|
|
@@ -13339,13 +13341,13 @@ function loadNoop(_src, onload) {
|
|
|
13339
13341
|
onload();
|
|
13340
13342
|
}
|
|
13341
13343
|
var mixpanel = init_as_module(loadNoop);
|
|
13342
|
-
let generation = 0;
|
|
13344
|
+
let generation$1 = 0;
|
|
13343
13345
|
let initialized = false;
|
|
13344
13346
|
let userId;
|
|
13345
13347
|
const subscribers = /* @__PURE__ */ new Set();
|
|
13346
13348
|
const initializationSubscribers = /* @__PURE__ */ new Set();
|
|
13347
13349
|
function invalidate$1() {
|
|
13348
|
-
generation++;
|
|
13350
|
+
generation$1++;
|
|
13349
13351
|
subscribers.forEach((notify) => notify());
|
|
13350
13352
|
}
|
|
13351
13353
|
function beginInitialization() {
|
|
@@ -13361,8 +13363,8 @@ function identify$2(nextUserId) {
|
|
|
13361
13363
|
}
|
|
13362
13364
|
}
|
|
13363
13365
|
function capture() {
|
|
13364
|
-
const captured = generation;
|
|
13365
|
-
return () => captured === generation;
|
|
13366
|
+
const captured = generation$1;
|
|
13367
|
+
return () => captured === generation$1;
|
|
13366
13368
|
}
|
|
13367
13369
|
function onChange(notify) {
|
|
13368
13370
|
subscribers.add(notify);
|
|
@@ -13471,7 +13473,7 @@ function observeIdentifyResult(stage, report, onTimeout) {
|
|
|
13471
13473
|
}, 5e3);
|
|
13472
13474
|
return { complete };
|
|
13473
13475
|
}
|
|
13474
|
-
const version = "1.1.8-alpha.
|
|
13476
|
+
const version = "1.1.8-alpha.3";
|
|
13475
13477
|
const MIXPANEL_DISTINCT_ID_CACHE_KEY = "mp_distinct_id";
|
|
13476
13478
|
const readinessSubscribers$1 = /* @__PURE__ */ new Set();
|
|
13477
13479
|
let initializing = false;
|
|
@@ -13501,6 +13503,7 @@ function init$2(mixpanelToken, debug = false, proxyUrl) {
|
|
|
13501
13503
|
return new Promise((resolve) => {
|
|
13502
13504
|
mixpanel.init(mixpanelToken, {
|
|
13503
13505
|
debug,
|
|
13506
|
+
batch_flush_interval_ms: 1e3,
|
|
13504
13507
|
loaded: () => {
|
|
13505
13508
|
if (attempt !== initialization$2) {
|
|
13506
13509
|
resolve();
|
|
@@ -13528,34 +13531,43 @@ function identify$1(userId2, properties, report) {
|
|
|
13528
13531
|
trackingLifecycle.identify(userId2);
|
|
13529
13532
|
mixpanel.identify(userId2);
|
|
13530
13533
|
if (!updateCachedDistinctId(userId2)) report == null ? void 0 : report("cache", "unavailable");
|
|
13531
|
-
|
|
13534
|
+
writePeopleProperties(properties, report);
|
|
13535
|
+
}
|
|
13536
|
+
function attachProperty(key, value) {
|
|
13537
|
+
if (!isReady()) {
|
|
13538
|
+
return;
|
|
13539
|
+
}
|
|
13540
|
+
mixpanel.people.union(key, [value]);
|
|
13541
|
+
}
|
|
13542
|
+
function setPeopleProperties(properties, report, onAccepted) {
|
|
13543
|
+
if (!isReady()) {
|
|
13544
|
+
return;
|
|
13545
|
+
}
|
|
13546
|
+
writePeopleProperties(properties, report, onAccepted);
|
|
13547
|
+
}
|
|
13548
|
+
function restorePeopleProperties(userId2, properties, report, onAccepted) {
|
|
13549
|
+
if (!isReady() || mixpanel.get_distinct_id() !== userId2) return;
|
|
13550
|
+
mixpanel.identify(userId2);
|
|
13551
|
+
writePeopleProperties(properties, report, onAccepted);
|
|
13552
|
+
}
|
|
13553
|
+
function writePeopleProperties(properties, report, onAccepted) {
|
|
13554
|
+
if (!report && !onAccepted) {
|
|
13532
13555
|
mixpanel.people.set(properties);
|
|
13533
13556
|
return;
|
|
13534
13557
|
}
|
|
13535
|
-
const observer = observeIdentifyResult("people", report);
|
|
13558
|
+
const observer = report ? observeIdentifyResult("people", report) : void 0;
|
|
13536
13559
|
try {
|
|
13537
13560
|
mixpanel.people.set(properties, (response) => {
|
|
13538
13561
|
const status = typeof response === "number" ? response : response == null ? void 0 : response.status;
|
|
13539
|
-
|
|
13562
|
+
if (status === 1) onAccepted == null ? void 0 : onAccepted();
|
|
13563
|
+
observer == null ? void 0 : observer.complete(
|
|
13540
13564
|
status === 1 ? void 0 : status === 0 ? "failed" : "unconfirmed"
|
|
13541
13565
|
);
|
|
13542
13566
|
});
|
|
13543
13567
|
} catch {
|
|
13544
|
-
observer.complete("failed");
|
|
13568
|
+
observer == null ? void 0 : observer.complete("failed");
|
|
13545
13569
|
}
|
|
13546
13570
|
}
|
|
13547
|
-
function attachProperty(key, value) {
|
|
13548
|
-
if (!isReady()) {
|
|
13549
|
-
return;
|
|
13550
|
-
}
|
|
13551
|
-
mixpanel.people.union(key, [value]);
|
|
13552
|
-
}
|
|
13553
|
-
function setPeopleProperties(properties) {
|
|
13554
|
-
if (!isReady()) {
|
|
13555
|
-
return;
|
|
13556
|
-
}
|
|
13557
|
-
mixpanel.people.set(properties);
|
|
13558
|
-
}
|
|
13559
13571
|
function isReady() {
|
|
13560
13572
|
return !initializing && window.mixpanel !== void 0;
|
|
13561
13573
|
}
|
|
@@ -13566,8 +13578,7 @@ function track(eventName, properties) {
|
|
|
13566
13578
|
mixpanel.track(eventName, { ...properties, "Reservamos Version": version });
|
|
13567
13579
|
}
|
|
13568
13580
|
const getMixpanelDistinctId = () => {
|
|
13569
|
-
|
|
13570
|
-
const distinctId = (_a = mixpanel == null ? void 0 : mixpanel.get_distinct_id) == null ? void 0 : _a.call(mixpanel);
|
|
13581
|
+
const distinctId = isReady() ? mixpanel.get_distinct_id() : null;
|
|
13571
13582
|
if (distinctId) {
|
|
13572
13583
|
updateCachedDistinctId(distinctId);
|
|
13573
13584
|
return distinctId;
|
|
@@ -13595,6 +13606,7 @@ const mixpanelService = {
|
|
|
13595
13606
|
identify: identify$1,
|
|
13596
13607
|
attachProperty,
|
|
13597
13608
|
setPeopleProperties,
|
|
13609
|
+
restorePeopleProperties,
|
|
13598
13610
|
getMixpanelDistinctId
|
|
13599
13611
|
};
|
|
13600
13612
|
const DEFAULT_CACHE_NAME = "default_fingerprint_cache";
|
|
@@ -13602,7 +13614,10 @@ const DEFAULT_CACHE_TIME_IN_DAYS = 7;
|
|
|
13602
13614
|
const PROXY_QUERY_PARAM = "apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>";
|
|
13603
13615
|
let fingerprintAgentReady = false;
|
|
13604
13616
|
let initialization$1 = 0;
|
|
13617
|
+
let startedInitialization = -1;
|
|
13605
13618
|
const readinessSubscribers = /* @__PURE__ */ new Set();
|
|
13619
|
+
const waitingConsumers = /* @__PURE__ */ new Set();
|
|
13620
|
+
let pendingIdentification;
|
|
13606
13621
|
function onReady(notify) {
|
|
13607
13622
|
readinessSubscribers.add(notify);
|
|
13608
13623
|
return () => {
|
|
@@ -13612,6 +13627,8 @@ function onReady(notify) {
|
|
|
13612
13627
|
function invalidate() {
|
|
13613
13628
|
initialization$1++;
|
|
13614
13629
|
fingerprintAgentReady = false;
|
|
13630
|
+
pendingIdentification = void 0;
|
|
13631
|
+
waitingConsumers.forEach((cancel) => cancel());
|
|
13615
13632
|
}
|
|
13616
13633
|
const getExpirationDate = (cacheTimeInDays) => {
|
|
13617
13634
|
const currentDate = /* @__PURE__ */ new Date();
|
|
@@ -13658,7 +13675,8 @@ async function initFingerprint(apiKey, proxyUrl) {
|
|
|
13658
13675
|
customEndpointArray.unshift(proxyUrl);
|
|
13659
13676
|
customScriptEndpointArray.unshift(buildProxyUrl(proxyUrl));
|
|
13660
13677
|
}
|
|
13661
|
-
invalidate();
|
|
13678
|
+
if (startedInitialization === initialization$1) invalidate();
|
|
13679
|
+
startedInitialization = initialization$1;
|
|
13662
13680
|
const attempt = initialization$1;
|
|
13663
13681
|
window.fingerprintConfig = {};
|
|
13664
13682
|
const client = new FpjsClient({
|
|
@@ -13678,6 +13696,7 @@ async function initFingerprint(apiKey, proxyUrl) {
|
|
|
13678
13696
|
} catch (error) {
|
|
13679
13697
|
if (window.fpClient === client && attempt === initialization$1) {
|
|
13680
13698
|
fingerprintAgentReady = false;
|
|
13699
|
+
waitingConsumers.forEach((cancel) => cancel());
|
|
13681
13700
|
}
|
|
13682
13701
|
console.error("Error initializing identification service:", error);
|
|
13683
13702
|
throw error;
|
|
@@ -13704,12 +13723,51 @@ async function identifyVisitor(ignoreCache = false, context) {
|
|
|
13704
13723
|
return requestIdentification(ignoreCache, context);
|
|
13705
13724
|
}
|
|
13706
13725
|
async function requestIdentification(ignoreCache, context) {
|
|
13726
|
+
if (!ignoreCache && (pendingIdentification == null ? void 0 : pendingIdentification.isCurrent())) {
|
|
13727
|
+
for (const participant of pendingIdentification.contexts) {
|
|
13728
|
+
if (participant && !participant.isActive())
|
|
13729
|
+
pendingIdentification.contexts.delete(participant);
|
|
13730
|
+
}
|
|
13731
|
+
pendingIdentification.contexts.add(context);
|
|
13732
|
+
return pendingIdentification.promise;
|
|
13733
|
+
}
|
|
13734
|
+
const contexts = /* @__PURE__ */ new Set([context]);
|
|
13735
|
+
const attempt = initialization$1;
|
|
13736
|
+
const currentLifecycle = trackingLifecycle.capture();
|
|
13737
|
+
const isCurrent = () => attempt === initialization$1 && currentLifecycle();
|
|
13738
|
+
const sharedContext = {
|
|
13739
|
+
isActive: () => isCurrent() && [...contexts].some(
|
|
13740
|
+
(participant) => !participant || participant.isActive()
|
|
13741
|
+
),
|
|
13742
|
+
report: (...args) => {
|
|
13743
|
+
for (const participant of contexts) {
|
|
13744
|
+
if (participant == null ? void 0 : participant.isActive()) participant.report(...args);
|
|
13745
|
+
}
|
|
13746
|
+
}
|
|
13747
|
+
};
|
|
13748
|
+
const request = {
|
|
13749
|
+
contexts,
|
|
13750
|
+
isCurrent,
|
|
13751
|
+
promise: performIdentification(
|
|
13752
|
+
ignoreCache,
|
|
13753
|
+
sharedContext,
|
|
13754
|
+
() => contexts.has(void 0)
|
|
13755
|
+
)
|
|
13756
|
+
};
|
|
13757
|
+
pendingIdentification = request;
|
|
13758
|
+
const clear = () => {
|
|
13759
|
+
if (pendingIdentification === request) pendingIdentification = void 0;
|
|
13760
|
+
};
|
|
13761
|
+
void request.promise.then(clear, clear);
|
|
13762
|
+
return request.promise;
|
|
13763
|
+
}
|
|
13764
|
+
async function performIdentification(ignoreCache, context, hasUnscopedConsumer) {
|
|
13707
13765
|
if (!isFingerprintReady()) {
|
|
13708
13766
|
throw new Error("Identification service is not initialized.");
|
|
13709
13767
|
}
|
|
13710
13768
|
try {
|
|
13711
13769
|
const result = await window.fpClient.getVisitorData({}, ignoreCache);
|
|
13712
|
-
if (
|
|
13770
|
+
if (context.isActive()) {
|
|
13713
13771
|
try {
|
|
13714
13772
|
setCachedFingerprint(result.visitorId);
|
|
13715
13773
|
} catch {
|
|
@@ -13721,8 +13779,9 @@ async function requestIdentification(ignoreCache, context) {
|
|
|
13721
13779
|
"Visitor Found": result.visitorFound
|
|
13722
13780
|
});
|
|
13723
13781
|
} catch (error) {
|
|
13724
|
-
|
|
13725
|
-
|
|
13782
|
+
context.report("fingerprint", "failed");
|
|
13783
|
+
if (hasUnscopedConsumer())
|
|
13784
|
+
console.error("Error updating Mixpanel visitor profile:", error);
|
|
13726
13785
|
}
|
|
13727
13786
|
}
|
|
13728
13787
|
}
|
|
@@ -13734,10 +13793,46 @@ async function requestIdentification(ignoreCache, context) {
|
|
|
13734
13793
|
cacheHit: result.cacheHit
|
|
13735
13794
|
};
|
|
13736
13795
|
} catch (error) {
|
|
13737
|
-
if (
|
|
13796
|
+
if (hasUnscopedConsumer())
|
|
13797
|
+
console.error("Error retrieving fingerprint:", error);
|
|
13738
13798
|
throw error;
|
|
13739
13799
|
}
|
|
13740
13800
|
}
|
|
13801
|
+
function waitForFingerprintId(timeoutMs = 2e3) {
|
|
13802
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0 || timeoutMs > 2147483647)
|
|
13803
|
+
return Promise.resolve(null);
|
|
13804
|
+
const cached = getCachedFingerprint();
|
|
13805
|
+
if (cached) return Promise.resolve(cached);
|
|
13806
|
+
return new Promise((resolve) => {
|
|
13807
|
+
let active = true;
|
|
13808
|
+
let started = false;
|
|
13809
|
+
const finish = (visitorId) => {
|
|
13810
|
+
if (!active) return;
|
|
13811
|
+
active = false;
|
|
13812
|
+
clearTimeout(timer);
|
|
13813
|
+
stopReady();
|
|
13814
|
+
stopLifecycle();
|
|
13815
|
+
waitingConsumers.delete(cancel);
|
|
13816
|
+
resolve(visitorId);
|
|
13817
|
+
};
|
|
13818
|
+
const cancel = () => finish(null);
|
|
13819
|
+
const start = () => {
|
|
13820
|
+
if (!active || started || !isFingerprintReady()) return;
|
|
13821
|
+
started = true;
|
|
13822
|
+
const identity = getFingerprint(false, {
|
|
13823
|
+
// Caller timeout ends waiting; the shared request still checks its lifecycle.
|
|
13824
|
+
isActive: () => true,
|
|
13825
|
+
report: () => void 0
|
|
13826
|
+
});
|
|
13827
|
+
void identity.then((visitorId) => finish(visitorId || null), cancel);
|
|
13828
|
+
};
|
|
13829
|
+
const timer = setTimeout(cancel, timeoutMs);
|
|
13830
|
+
const stopReady = onReady(start);
|
|
13831
|
+
const stopLifecycle = trackingLifecycle.onChange(cancel);
|
|
13832
|
+
waitingConsumers.add(cancel);
|
|
13833
|
+
start();
|
|
13834
|
+
});
|
|
13835
|
+
}
|
|
13741
13836
|
function isFingerprintReady() {
|
|
13742
13837
|
return window.fpClient !== void 0 && fingerprintAgentReady;
|
|
13743
13838
|
}
|
|
@@ -13748,7 +13843,8 @@ const fingerprintService = {
|
|
|
13748
13843
|
isFingerprintReady,
|
|
13749
13844
|
onReady,
|
|
13750
13845
|
invalidate,
|
|
13751
|
-
getCachedFingerprint
|
|
13846
|
+
getCachedFingerprint,
|
|
13847
|
+
waitForFingerprintId
|
|
13752
13848
|
};
|
|
13753
13849
|
trackingLifecycle.onInitialization(invalidate);
|
|
13754
13850
|
function createPendingWorkQueue(options) {
|
|
@@ -14073,7 +14169,8 @@ const passengersCreatedSchema = z.object({
|
|
|
14073
14169
|
"Trip Count": intField("Trip Count").optional(),
|
|
14074
14170
|
"Total": numberField("Total"),
|
|
14075
14171
|
"product": productValidation,
|
|
14076
|
-
"Passengers": arrayField(passengerSchema, "Passengers", 1).optional()
|
|
14172
|
+
"Passengers": arrayField(passengerSchema, "Passengers", 1).optional(),
|
|
14173
|
+
"Coupon": stringField("Coupon").optional()
|
|
14077
14174
|
}).strict();
|
|
14078
14175
|
const EVENT_NAME$8 = "Passengers Created";
|
|
14079
14176
|
function trackPassengersCreated(eventProps, meta = {}) {
|
|
@@ -14141,7 +14238,8 @@ const purchaseConfirmationSchema = z.object({
|
|
|
14141
14238
|
"Operation Id": z.string().min(1, "Operation Id is required"),
|
|
14142
14239
|
"Payment Status": z.enum(["confirmed", "pending_pix"]),
|
|
14143
14240
|
"Payment Type": z.string().optional(),
|
|
14144
|
-
"Total": z.number().optional()
|
|
14241
|
+
"Total": z.number().optional(),
|
|
14242
|
+
"product": productValidation.optional()
|
|
14145
14243
|
}).strict();
|
|
14146
14244
|
const EVENT_NAME$4 = "Purchase Confirmation Viewed";
|
|
14147
14245
|
function trackPurchaseConfirmation(eventData, meta = {}) {
|
|
@@ -14325,11 +14423,285 @@ const validatorService = {
|
|
|
14325
14423
|
parseIdentifyProps,
|
|
14326
14424
|
validateProps
|
|
14327
14425
|
};
|
|
14426
|
+
function isCamelCase(word) {
|
|
14427
|
+
if (!word || word.includes(" ")) return false;
|
|
14428
|
+
if (word[0] !== word[0].toLowerCase()) return false;
|
|
14429
|
+
if (/[^a-zA-Z]/.test(word)) return false;
|
|
14430
|
+
if (!/[A-Z]/.test(word)) return false;
|
|
14431
|
+
return true;
|
|
14432
|
+
}
|
|
14433
|
+
const CreateAnonymousProfileSchema = z.object({
|
|
14434
|
+
email: z.string().email().optional(),
|
|
14435
|
+
phone: z.string().optional(),
|
|
14436
|
+
cpf: z.string().optional(),
|
|
14437
|
+
passport: z.string().optional(),
|
|
14438
|
+
rg: z.string().optional(),
|
|
14439
|
+
firstName: z.string().optional(),
|
|
14440
|
+
lastName: z.string().optional()
|
|
14441
|
+
}).refine((data) => data.email || data.phone, {
|
|
14442
|
+
message: "At least one of 'email' or 'phone' must be provided"
|
|
14443
|
+
});
|
|
14444
|
+
function getAnonymousProfilePayload(values, identifiersProps) {
|
|
14445
|
+
let identifier_key = "phone";
|
|
14446
|
+
let identifier_value = values.phone || "";
|
|
14447
|
+
const identifiers = [];
|
|
14448
|
+
const details = {};
|
|
14449
|
+
if (values.email) {
|
|
14450
|
+
identifier_key = "email";
|
|
14451
|
+
identifier_value = values.email;
|
|
14452
|
+
}
|
|
14453
|
+
const allowedKeys = [
|
|
14454
|
+
"cpf",
|
|
14455
|
+
"passport",
|
|
14456
|
+
"rg",
|
|
14457
|
+
"email",
|
|
14458
|
+
"phone",
|
|
14459
|
+
"salesforceid"
|
|
14460
|
+
];
|
|
14461
|
+
const allowedKeysDetails = ["name", "firstName", "lastName"];
|
|
14462
|
+
Object.entries(values).forEach(([key, value]) => {
|
|
14463
|
+
key = isCamelCase(key) ? key : key.toLocaleLowerCase();
|
|
14464
|
+
if (allowedKeys.includes(key) && value) {
|
|
14465
|
+
if (key !== identifier_key) {
|
|
14466
|
+
identifiers.push({ key, value });
|
|
14467
|
+
}
|
|
14468
|
+
} else if (allowedKeysDetails.includes(key) && value) {
|
|
14469
|
+
details[key] = value;
|
|
14470
|
+
}
|
|
14471
|
+
});
|
|
14472
|
+
if (identifiersProps.length) {
|
|
14473
|
+
identifiersProps.forEach((item) => identifiers.push(item));
|
|
14474
|
+
}
|
|
14475
|
+
return {
|
|
14476
|
+
identifier_key,
|
|
14477
|
+
identifier_value,
|
|
14478
|
+
details,
|
|
14479
|
+
identifiers
|
|
14480
|
+
};
|
|
14481
|
+
}
|
|
14482
|
+
async function createAnonymousProfile(payload) {
|
|
14483
|
+
try {
|
|
14484
|
+
return await requestAnonymousProfile(payload);
|
|
14485
|
+
} catch (error) {
|
|
14486
|
+
console.error("Could not create anonymous profile:", error);
|
|
14487
|
+
return void 0;
|
|
14488
|
+
}
|
|
14489
|
+
}
|
|
14490
|
+
function createAnonymousProfileForIdentify(payload, report) {
|
|
14491
|
+
return requestAnonymousProfile(payload, report);
|
|
14492
|
+
}
|
|
14493
|
+
async function requestAnonymousProfile(payload, report) {
|
|
14494
|
+
return requestPreparedAnonymousProfile(
|
|
14495
|
+
prepareAnonymousProfileForIdentify(payload, report)
|
|
14496
|
+
);
|
|
14497
|
+
}
|
|
14498
|
+
function prepareAnonymousProfileForIdentify(payload, report) {
|
|
14499
|
+
validatorService.validateProps(payload, CreateAnonymousProfileSchema);
|
|
14500
|
+
const identifiers = [];
|
|
14501
|
+
const readIdentifier = (read2) => {
|
|
14502
|
+
if (!report) return read2();
|
|
14503
|
+
try {
|
|
14504
|
+
return read2();
|
|
14505
|
+
} catch {
|
|
14506
|
+
report("cache", "unavailable");
|
|
14507
|
+
return null;
|
|
14508
|
+
}
|
|
14509
|
+
};
|
|
14510
|
+
const userFingerprintId = readIdentifier(
|
|
14511
|
+
fingerprintService.getCachedFingerprint
|
|
14512
|
+
);
|
|
14513
|
+
const distinctId = readIdentifier(mixpanelService.getMixpanelDistinctId);
|
|
14514
|
+
if (userFingerprintId)
|
|
14515
|
+
identifiers.push({ key: "fingerprint", value: userFingerprintId });
|
|
14516
|
+
if (distinctId) identifiers.push({ key: "distinct_id", value: distinctId });
|
|
14517
|
+
return getAnonymousProfilePayload(payload, identifiers);
|
|
14518
|
+
}
|
|
14519
|
+
function requestPreparedAnonymousProfile(payload) {
|
|
14520
|
+
return a$1.profiles.createAnonymousProfile(payload);
|
|
14521
|
+
}
|
|
14522
|
+
const STORAGE_KEY = "reservamos_pending_profile_v1";
|
|
14523
|
+
const LIFETIME_MS = 10 * 60 * 1e3;
|
|
14524
|
+
const MAX_ATTEMPTS = 3;
|
|
14525
|
+
const MAX_BYTES = 4096;
|
|
14526
|
+
const profileIdSchema = z.union([
|
|
14527
|
+
z.string().min(1),
|
|
14528
|
+
z.number().int().positive()
|
|
14529
|
+
]);
|
|
14530
|
+
const requestSchema = z.object({
|
|
14531
|
+
identifier_key: z.enum(["email", "phone"]),
|
|
14532
|
+
identifier_value: z.string().min(1),
|
|
14533
|
+
identifiers: z.array(
|
|
14534
|
+
z.object({ key: z.string().min(1), value: z.string().min(1) }).strict()
|
|
14535
|
+
),
|
|
14536
|
+
details: z.record(z.string())
|
|
14537
|
+
}).strict();
|
|
14538
|
+
const pendingSchema = z.object({
|
|
14539
|
+
version: z.literal(1),
|
|
14540
|
+
id: z.string().min(1),
|
|
14541
|
+
userId: z.string().min(1),
|
|
14542
|
+
scope: z.string().min(1),
|
|
14543
|
+
expiresAt: z.number().int(),
|
|
14544
|
+
attempts: z.number().int().min(1).max(MAX_ATTEMPTS),
|
|
14545
|
+
request: requestSchema.optional(),
|
|
14546
|
+
profileId: profileIdSchema.optional()
|
|
14547
|
+
}).strict().refine((entry) => entry.request || entry.profileId);
|
|
14548
|
+
let scope;
|
|
14549
|
+
let generation = 0;
|
|
14550
|
+
function remove(report, id) {
|
|
14551
|
+
try {
|
|
14552
|
+
if (id) {
|
|
14553
|
+
const stored = JSON.parse(
|
|
14554
|
+
sessionStorage.getItem(STORAGE_KEY) || "null"
|
|
14555
|
+
);
|
|
14556
|
+
if ((stored == null ? void 0 : stored.id) !== id) return;
|
|
14557
|
+
}
|
|
14558
|
+
sessionStorage.removeItem(STORAGE_KEY);
|
|
14559
|
+
} catch {
|
|
14560
|
+
report("cache", "unavailable");
|
|
14561
|
+
}
|
|
14562
|
+
}
|
|
14563
|
+
function save(entry, report) {
|
|
14564
|
+
try {
|
|
14565
|
+
const serialized = JSON.stringify(entry);
|
|
14566
|
+
if (new Blob([serialized]).size > MAX_BYTES) {
|
|
14567
|
+
remove(report);
|
|
14568
|
+
report("cache", "unavailable");
|
|
14569
|
+
return false;
|
|
14570
|
+
}
|
|
14571
|
+
sessionStorage.setItem(STORAGE_KEY, serialized);
|
|
14572
|
+
return true;
|
|
14573
|
+
} catch {
|
|
14574
|
+
remove(report);
|
|
14575
|
+
report("cache", "unavailable");
|
|
14576
|
+
return false;
|
|
14577
|
+
}
|
|
14578
|
+
}
|
|
14579
|
+
function read(report) {
|
|
14580
|
+
try {
|
|
14581
|
+
const serialized = sessionStorage.getItem(STORAGE_KEY);
|
|
14582
|
+
if (!serialized) return void 0;
|
|
14583
|
+
if (new Blob([serialized]).size > MAX_BYTES) throw new Error();
|
|
14584
|
+
const entry = pendingSchema.parse(JSON.parse(serialized));
|
|
14585
|
+
if (entry.expiresAt <= Date.now() || entry.expiresAt > Date.now() + LIFETIME_MS) {
|
|
14586
|
+
remove(report);
|
|
14587
|
+
return void 0;
|
|
14588
|
+
}
|
|
14589
|
+
return entry;
|
|
14590
|
+
} catch {
|
|
14591
|
+
remove(report);
|
|
14592
|
+
report("cache", "unavailable");
|
|
14593
|
+
return void 0;
|
|
14594
|
+
}
|
|
14595
|
+
}
|
|
14596
|
+
function currentUserIs(userId2) {
|
|
14597
|
+
return mixpanelService.isReady() && mixpanelService.getMixpanelDistinctId() === userId2;
|
|
14598
|
+
}
|
|
14599
|
+
async function resolveProfile(userId2, properties, isCurrent, report, entry, recovering = false) {
|
|
14600
|
+
if (!isCurrent()) return void 0;
|
|
14601
|
+
const profile = (entry == null ? void 0 : entry.profileId) !== void 0 ? { id: entry.profileId } : await waitForIdentifyStage(
|
|
14602
|
+
"profile",
|
|
14603
|
+
3e3,
|
|
14604
|
+
(context) => isCurrent() ? (entry == null ? void 0 : entry.request) ? requestPreparedAnonymousProfile(entry.request) : createAnonymousProfileForIdentify(
|
|
14605
|
+
{ ...properties },
|
|
14606
|
+
context.report
|
|
14607
|
+
) : Promise.resolve(void 0),
|
|
14608
|
+
report
|
|
14609
|
+
);
|
|
14610
|
+
if (!isCurrent()) return void 0;
|
|
14611
|
+
if (!profile) {
|
|
14612
|
+
if (entry && entry.attempts >= MAX_ATTEMPTS) remove(report, entry.id);
|
|
14613
|
+
return void 0;
|
|
14614
|
+
}
|
|
14615
|
+
const parsedId = profileIdSchema.safeParse(profile.id);
|
|
14616
|
+
if (!parsedId.success) {
|
|
14617
|
+
report("profile", "failed");
|
|
14618
|
+
return void 0;
|
|
14619
|
+
}
|
|
14620
|
+
const profileId = parsedId.data;
|
|
14621
|
+
if (entry) save({ ...entry, request: void 0, profileId }, report);
|
|
14622
|
+
const accepted = () => {
|
|
14623
|
+
if (entry && isCurrent()) remove(report, entry.id);
|
|
14624
|
+
};
|
|
14625
|
+
try {
|
|
14626
|
+
const properties2 = { reservamos_one_id: profileId };
|
|
14627
|
+
if (recovering) {
|
|
14628
|
+
mixpanelService.restorePeopleProperties(
|
|
14629
|
+
userId2,
|
|
14630
|
+
properties2,
|
|
14631
|
+
report,
|
|
14632
|
+
accepted
|
|
14633
|
+
);
|
|
14634
|
+
} else if (entry) {
|
|
14635
|
+
mixpanelService.setPeopleProperties(properties2, report, accepted);
|
|
14636
|
+
} else {
|
|
14637
|
+
mixpanelService.setPeopleProperties(properties2, report);
|
|
14638
|
+
}
|
|
14639
|
+
} catch {
|
|
14640
|
+
report("profile", "failed");
|
|
14641
|
+
}
|
|
14642
|
+
return { id: profileId };
|
|
14643
|
+
}
|
|
14644
|
+
function enrich(userId2, properties, isActive, report) {
|
|
14645
|
+
if (!isActive()) return Promise.resolve(void 0);
|
|
14646
|
+
const attempt = ++generation;
|
|
14647
|
+
let request;
|
|
14648
|
+
if (scope) {
|
|
14649
|
+
try {
|
|
14650
|
+
const prepared = requestSchema.safeParse(
|
|
14651
|
+
prepareAnonymousProfileForIdentify({ ...properties }, report)
|
|
14652
|
+
);
|
|
14653
|
+
if (prepared.success) request = prepared.data;
|
|
14654
|
+
} catch {
|
|
14655
|
+
}
|
|
14656
|
+
}
|
|
14657
|
+
const entry = scope && request ? {
|
|
14658
|
+
version: 1,
|
|
14659
|
+
id: `${Date.now()}-${Math.random()}`,
|
|
14660
|
+
userId: userId2,
|
|
14661
|
+
scope,
|
|
14662
|
+
expiresAt: Date.now() + LIFETIME_MS,
|
|
14663
|
+
attempts: 1,
|
|
14664
|
+
request
|
|
14665
|
+
} : void 0;
|
|
14666
|
+
if (entry) save(entry, report);
|
|
14667
|
+
else if (scope) remove(report);
|
|
14668
|
+
const isCurrent = () => attempt === generation && isActive() && (!entry || Date.now() < entry.expiresAt) && (!scope || currentUserIs(userId2));
|
|
14669
|
+
return resolveProfile(userId2, properties, isCurrent, report, entry);
|
|
14670
|
+
}
|
|
14671
|
+
function initialize(configuration) {
|
|
14672
|
+
scope = JSON.stringify([
|
|
14673
|
+
configuration.project,
|
|
14674
|
+
configuration.proxy ?? "",
|
|
14675
|
+
configuration.apiBaseUrl,
|
|
14676
|
+
configuration.appName ?? ""
|
|
14677
|
+
]);
|
|
14678
|
+
const attempt = ++generation;
|
|
14679
|
+
const report = createIdentifyReporter();
|
|
14680
|
+
const entry = read(report);
|
|
14681
|
+
if (!entry) return;
|
|
14682
|
+
if (entry.scope !== scope || !currentUserIs(entry.userId) || entry.profileId === void 0 && entry.attempts >= MAX_ATTEMPTS) {
|
|
14683
|
+
remove(report, entry.id);
|
|
14684
|
+
return;
|
|
14685
|
+
}
|
|
14686
|
+
const lifecycle = trackingLifecycle.capture();
|
|
14687
|
+
const isCurrent = () => attempt === generation && lifecycle() && Date.now() < entry.expiresAt && currentUserIs(entry.userId);
|
|
14688
|
+
const resumed = {
|
|
14689
|
+
...entry,
|
|
14690
|
+
attempts: entry.attempts + (entry.profileId === void 0 ? 1 : 0)
|
|
14691
|
+
};
|
|
14692
|
+
if (entry.profileId === void 0 && !save(resumed, report)) return;
|
|
14693
|
+
const scopedReport = (...args) => {
|
|
14694
|
+
if (isCurrent()) report(...args);
|
|
14695
|
+
};
|
|
14696
|
+
void resolveProfile(entry.userId, {}, isCurrent, scopedReport, resumed, true);
|
|
14697
|
+
}
|
|
14698
|
+
const profileEnrichment = { enrich, initialize };
|
|
14328
14699
|
let initialization = 0;
|
|
14329
14700
|
function onLoaded() {
|
|
14330
14701
|
window.dispatchEvent(new CustomEvent("Tracker Ready"));
|
|
14331
14702
|
}
|
|
14332
14703
|
async function init$1(config) {
|
|
14704
|
+
var _a;
|
|
14333
14705
|
validatorService.parseInitProps(config);
|
|
14334
14706
|
const {
|
|
14335
14707
|
mixpanelToken,
|
|
@@ -14349,9 +14721,16 @@ async function init$1(config) {
|
|
|
14349
14721
|
if (appName2) {
|
|
14350
14722
|
configService.setAppName(appName2);
|
|
14351
14723
|
}
|
|
14352
|
-
|
|
14724
|
+
const coreConfig = configService.getCoreAPIConfig();
|
|
14725
|
+
a$1.setConfig(coreConfig);
|
|
14353
14726
|
onLoaded();
|
|
14354
14727
|
if (!isCurrent()) return;
|
|
14728
|
+
profileEnrichment.initialize({
|
|
14729
|
+
project: mixpanelToken,
|
|
14730
|
+
proxy: mixpanelProxyUrl,
|
|
14731
|
+
apiBaseUrl: coreConfig.baseUrl,
|
|
14732
|
+
appName: (_a = coreConfig.defaultHeaders) == null ? void 0 : _a["x-app-name"]
|
|
14733
|
+
});
|
|
14355
14734
|
await Promise.all([
|
|
14356
14735
|
initializeOptionalStage(
|
|
14357
14736
|
"fingerprint",
|
|
@@ -14366,7 +14745,7 @@ async function init$1(config) {
|
|
|
14366
14745
|
)
|
|
14367
14746
|
]);
|
|
14368
14747
|
}
|
|
14369
|
-
function initializeOptionalStage(stage,
|
|
14748
|
+
function initializeOptionalStage(stage, initialize2) {
|
|
14370
14749
|
return new Promise((resolve) => {
|
|
14371
14750
|
let active = true;
|
|
14372
14751
|
const finish = (reason) => {
|
|
@@ -14378,7 +14757,7 @@ function initializeOptionalStage(stage, initialize) {
|
|
|
14378
14757
|
resolve();
|
|
14379
14758
|
};
|
|
14380
14759
|
const timer = setTimeout(() => finish("timeout"), 3e3);
|
|
14381
|
-
void Promise.resolve().then(
|
|
14760
|
+
void Promise.resolve().then(initialize2).then(
|
|
14382
14761
|
() => finish(),
|
|
14383
14762
|
() => finish("failed")
|
|
14384
14763
|
);
|
|
@@ -14866,97 +15245,9 @@ function trackCustomEvent(eventName, eventData = {}, meta = {}) {
|
|
|
14866
15245
|
trackEventError(eventName, error, eventData);
|
|
14867
15246
|
}
|
|
14868
15247
|
}
|
|
14869
|
-
function isCamelCase(word) {
|
|
14870
|
-
if (!word || word.includes(" ")) return false;
|
|
14871
|
-
if (word[0] !== word[0].toLowerCase()) return false;
|
|
14872
|
-
if (/[^a-zA-Z]/.test(word)) return false;
|
|
14873
|
-
if (!/[A-Z]/.test(word)) return false;
|
|
14874
|
-
return true;
|
|
14875
|
-
}
|
|
14876
|
-
const CreateAnonymousProfileSchema = z.object({
|
|
14877
|
-
email: z.string().email().optional(),
|
|
14878
|
-
phone: z.string().optional(),
|
|
14879
|
-
cpf: z.string().optional(),
|
|
14880
|
-
passport: z.string().optional(),
|
|
14881
|
-
rg: z.string().optional(),
|
|
14882
|
-
firstName: z.string().optional(),
|
|
14883
|
-
lastName: z.string().optional()
|
|
14884
|
-
}).refine((data) => data.email || data.phone, {
|
|
14885
|
-
message: "At least one of 'email' or 'phone' must be provided"
|
|
14886
|
-
});
|
|
14887
|
-
function getAnonymousProfilePayload(values, identifiersProps) {
|
|
14888
|
-
let identifier_key = "phone";
|
|
14889
|
-
let identifier_value = values.phone || "";
|
|
14890
|
-
const identifiers = [];
|
|
14891
|
-
const details = {};
|
|
14892
|
-
if (values.email) {
|
|
14893
|
-
identifier_key = "email";
|
|
14894
|
-
identifier_value = values.email;
|
|
14895
|
-
}
|
|
14896
|
-
const allowedKeys = [
|
|
14897
|
-
"cpf",
|
|
14898
|
-
"passport",
|
|
14899
|
-
"rg",
|
|
14900
|
-
"email",
|
|
14901
|
-
"phone",
|
|
14902
|
-
"salesforceid"
|
|
14903
|
-
];
|
|
14904
|
-
const allowedKeysDetails = ["name", "firstName", "lastName"];
|
|
14905
|
-
Object.entries(values).forEach(([key, value]) => {
|
|
14906
|
-
key = isCamelCase(key) ? key : key.toLocaleLowerCase();
|
|
14907
|
-
if (allowedKeys.includes(key) && value) {
|
|
14908
|
-
if (key !== identifier_key) {
|
|
14909
|
-
identifiers.push({ key, value });
|
|
14910
|
-
}
|
|
14911
|
-
} else if (allowedKeysDetails.includes(key) && value) {
|
|
14912
|
-
details[key] = value;
|
|
14913
|
-
}
|
|
14914
|
-
});
|
|
14915
|
-
if (identifiersProps.length) {
|
|
14916
|
-
identifiersProps.forEach((item) => identifiers.push(item));
|
|
14917
|
-
}
|
|
14918
|
-
return {
|
|
14919
|
-
identifier_key,
|
|
14920
|
-
identifier_value,
|
|
14921
|
-
details,
|
|
14922
|
-
identifiers
|
|
14923
|
-
};
|
|
14924
|
-
}
|
|
14925
|
-
async function createAnonymousProfile(payload) {
|
|
14926
|
-
try {
|
|
14927
|
-
return await requestAnonymousProfile(payload);
|
|
14928
|
-
} catch (error) {
|
|
14929
|
-
console.error("Could not create anonymous profile:", error);
|
|
14930
|
-
return void 0;
|
|
14931
|
-
}
|
|
14932
|
-
}
|
|
14933
|
-
function createAnonymousProfileForIdentify(payload, report) {
|
|
14934
|
-
return requestAnonymousProfile(payload, report);
|
|
14935
|
-
}
|
|
14936
|
-
async function requestAnonymousProfile(payload, report) {
|
|
14937
|
-
validatorService.validateProps(payload, CreateAnonymousProfileSchema);
|
|
14938
|
-
const identifiers = [];
|
|
14939
|
-
const readIdentifier = (read) => {
|
|
14940
|
-
if (!report) return read();
|
|
14941
|
-
try {
|
|
14942
|
-
return read();
|
|
14943
|
-
} catch {
|
|
14944
|
-
report("cache", "unavailable");
|
|
14945
|
-
return null;
|
|
14946
|
-
}
|
|
14947
|
-
};
|
|
14948
|
-
const userFingerprintId = readIdentifier(
|
|
14949
|
-
fingerprintService.getCachedFingerprint
|
|
14950
|
-
);
|
|
14951
|
-
const distinctId = readIdentifier(mixpanelService.getMixpanelDistinctId);
|
|
14952
|
-
if (userFingerprintId)
|
|
14953
|
-
identifiers.push({ key: "fingerprint", value: userFingerprintId });
|
|
14954
|
-
if (distinctId) identifiers.push({ key: "distinct_id", value: distinctId });
|
|
14955
|
-
const dataPayload = getAnonymousProfilePayload(payload, identifiers);
|
|
14956
|
-
return await a$1.profiles.createAnonymousProfile(dataPayload);
|
|
14957
|
-
}
|
|
14958
15248
|
const KNOWN_PROPERTIES = ["firstName", "lastName", "email", "phone"];
|
|
14959
15249
|
const FINGERPRINT_PROPERTY = "Known Fingerprints";
|
|
15250
|
+
let latestAttempt = 0;
|
|
14960
15251
|
function mapProperties(properties) {
|
|
14961
15252
|
const parsedProperties = {
|
|
14962
15253
|
$first_name: properties == null ? void 0 : properties.firstName,
|
|
@@ -15026,12 +15317,48 @@ const identifyWithLocation = async (userId2, properties, report) => {
|
|
|
15026
15317
|
else report("datalake", "failed");
|
|
15027
15318
|
}
|
|
15028
15319
|
};
|
|
15320
|
+
async function enrichProfileAndLocation(userId2, properties, isActive, report) {
|
|
15321
|
+
const profile = await profileEnrichment.enrich(
|
|
15322
|
+
userId2,
|
|
15323
|
+
properties,
|
|
15324
|
+
isActive,
|
|
15325
|
+
report
|
|
15326
|
+
);
|
|
15327
|
+
if (!isActive()) return;
|
|
15328
|
+
const enriched = {
|
|
15329
|
+
...properties,
|
|
15330
|
+
...profile && { reservamos_one_id: profile.id }
|
|
15331
|
+
};
|
|
15332
|
+
void identifyWithLocation(userId2, enriched, report);
|
|
15333
|
+
}
|
|
15334
|
+
async function enrichFingerprint(isActive, report) {
|
|
15335
|
+
const fingerprint = await waitForIdentifyStage(
|
|
15336
|
+
"fingerprint",
|
|
15337
|
+
2e3,
|
|
15338
|
+
(context) => !isActive() ? Promise.resolve("") : getFingerprintForIdentify({
|
|
15339
|
+
isActive: () => context.isActive() && isActive(),
|
|
15340
|
+
report: context.report
|
|
15341
|
+
}),
|
|
15342
|
+
report
|
|
15343
|
+
);
|
|
15344
|
+
if (!fingerprint || !isActive()) return;
|
|
15345
|
+
try {
|
|
15346
|
+
mixpanelService.attachProperty(FINGERPRINT_PROPERTY, fingerprint);
|
|
15347
|
+
} catch {
|
|
15348
|
+
report("fingerprint", "failed");
|
|
15349
|
+
}
|
|
15350
|
+
}
|
|
15029
15351
|
async function identify(userId2, properties = {}) {
|
|
15352
|
+
const attempt = ++latestAttempt;
|
|
15353
|
+
const input = { ...properties };
|
|
15030
15354
|
const report = createIdentifyReporter();
|
|
15031
|
-
|
|
15355
|
+
const initialLifecycle = trackingLifecycle.capture();
|
|
15356
|
+
if (!await waitForIdentifyReady(report) || attempt !== latestAttempt || !initialLifecycle())
|
|
15357
|
+
return;
|
|
15358
|
+
let submitted = false;
|
|
15032
15359
|
try {
|
|
15033
15360
|
try {
|
|
15034
|
-
validatorService.parseIdentifyProps(
|
|
15361
|
+
validatorService.parseIdentifyProps(input);
|
|
15035
15362
|
if (!userId2) {
|
|
15036
15363
|
report("validation", "invalid_input");
|
|
15037
15364
|
return;
|
|
@@ -15040,38 +15367,22 @@ async function identify(userId2, properties = {}) {
|
|
|
15040
15367
|
report("validation", "invalid_input");
|
|
15041
15368
|
return;
|
|
15042
15369
|
}
|
|
15043
|
-
const anonymousProfile = await waitForIdentifyStage(
|
|
15044
|
-
"profile",
|
|
15045
|
-
3e3,
|
|
15046
|
-
(context) => createAnonymousProfileForIdentify({ ...properties }, context.report),
|
|
15047
|
-
report
|
|
15048
|
-
);
|
|
15049
|
-
if (anonymousProfile) {
|
|
15050
|
-
properties.reservamos_one_id = anonymousProfile.id;
|
|
15051
|
-
}
|
|
15052
|
-
const mappedProps = mapProperties(properties);
|
|
15053
15370
|
try {
|
|
15054
|
-
mixpanelService.identify(userId2,
|
|
15371
|
+
mixpanelService.identify(userId2, mapProperties(input), report);
|
|
15055
15372
|
} catch {
|
|
15056
15373
|
report("mixpanel", "failed");
|
|
15374
|
+
return;
|
|
15057
15375
|
}
|
|
15058
|
-
const
|
|
15059
|
-
|
|
15060
|
-
|
|
15061
|
-
|
|
15062
|
-
|
|
15063
|
-
|
|
15064
|
-
|
|
15065
|
-
|
|
15066
|
-
mixpanelService.attachProperty(FINGERPRINT_PROPERTY, fingerprint);
|
|
15067
|
-
} catch {
|
|
15068
|
-
report("fingerprint", "failed");
|
|
15069
|
-
}
|
|
15070
|
-
}
|
|
15071
|
-
} catch {
|
|
15072
|
-
report("mixpanel", "failed");
|
|
15376
|
+
const currentLifecycle = trackingLifecycle.capture();
|
|
15377
|
+
const isActive = () => attempt === latestAttempt && currentLifecycle();
|
|
15378
|
+
const scopedReport = (...args) => {
|
|
15379
|
+
if (isActive()) report(...args);
|
|
15380
|
+
};
|
|
15381
|
+
submitted = true;
|
|
15382
|
+
void enrichProfileAndLocation(userId2, input, isActive, scopedReport);
|
|
15383
|
+
void enrichFingerprint(isActive, scopedReport);
|
|
15073
15384
|
} finally {
|
|
15074
|
-
void identifyWithLocation(userId2,
|
|
15385
|
+
if (!submitted) void identifyWithLocation(userId2, { ...input }, report);
|
|
15075
15386
|
}
|
|
15076
15387
|
}
|
|
15077
15388
|
z.object({
|
|
@@ -15273,6 +15584,7 @@ const analytics = {
|
|
|
15273
15584
|
identify,
|
|
15274
15585
|
identifiers: {
|
|
15275
15586
|
getFingerprintId: fingerprintService.getCachedFingerprint,
|
|
15587
|
+
waitForFingerprintId: fingerprintService.waitForFingerprintId,
|
|
15276
15588
|
getDistinctId: mixpanelService.getMixpanelDistinctId
|
|
15277
15589
|
},
|
|
15278
15590
|
profiles: {
|