@reservamos/browser-analytics 1.1.8-alpha.0 → 1.1.8-alpha.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.
@@ -11260,9 +11260,9 @@ MixpanelRecorder.prototype._flushEvents = addOptOutCheckMixpanelLib(function(dat
11260
11260
  if (deviceId) {
11261
11261
  reqParams["$device_id"] = deviceId;
11262
11262
  }
11263
- var userId = this._mixpanel.get_property("$user_id");
11264
- if (userId) {
11265
- reqParams["$user_id"] = userId;
11263
+ var userId2 = this._mixpanel.get_property("$user_id");
11264
+ if (userId2) {
11265
+ reqParams["$user_id"] = userId2;
11266
11266
  }
11267
11267
  if (CompressionStream) {
11268
11268
  var jsonStream = new Blob([eventsJson], { type: "application/json" }).stream();
@@ -13339,6 +13339,50 @@ function loadNoop(_src, onload) {
13339
13339
  onload();
13340
13340
  }
13341
13341
  var mixpanel = init_as_module(loadNoop);
13342
+ let generation = 0;
13343
+ let initialized = false;
13344
+ let userId;
13345
+ const subscribers = /* @__PURE__ */ new Set();
13346
+ const initializationSubscribers = /* @__PURE__ */ new Set();
13347
+ function invalidate$1() {
13348
+ generation++;
13349
+ subscribers.forEach((notify) => notify());
13350
+ }
13351
+ function beginInitialization() {
13352
+ if (initialized) invalidate$1();
13353
+ initialized = true;
13354
+ userId = void 0;
13355
+ initializationSubscribers.forEach((notify) => notify());
13356
+ }
13357
+ function identify$2(nextUserId) {
13358
+ if (userId !== nextUserId) {
13359
+ userId = nextUserId;
13360
+ invalidate$1();
13361
+ }
13362
+ }
13363
+ function capture() {
13364
+ const captured = generation;
13365
+ return () => captured === generation;
13366
+ }
13367
+ function onChange(notify) {
13368
+ subscribers.add(notify);
13369
+ return () => {
13370
+ subscribers.delete(notify);
13371
+ };
13372
+ }
13373
+ function onInitialization(notify) {
13374
+ initializationSubscribers.add(notify);
13375
+ return () => {
13376
+ initializationSubscribers.delete(notify);
13377
+ };
13378
+ }
13379
+ const trackingLifecycle = {
13380
+ beginInitialization,
13381
+ identify: identify$2,
13382
+ capture,
13383
+ onChange,
13384
+ onInitialization
13385
+ };
13342
13386
  function createIdentifyReporter() {
13343
13387
  const reported = /* @__PURE__ */ new Set();
13344
13388
  return (stage, reason, httpStatus) => {
@@ -13373,16 +13417,16 @@ function waitForIdentifyReady(report) {
13373
13417
  if (!active) return;
13374
13418
  active = false;
13375
13419
  clearTimeout(timer);
13376
- window.removeEventListener("Tracker Ready", onReady);
13420
+ window.removeEventListener("Tracker Ready", onReady2);
13377
13421
  if (!ready) report("readiness", "timeout");
13378
13422
  resolve(ready);
13379
13423
  };
13380
- const onReady = () => {
13424
+ const onReady2 = () => {
13381
13425
  if (mixpanelService.isReady()) finish(true);
13382
13426
  };
13383
13427
  const timer = setTimeout(() => finish(false), 5e3);
13384
- window.addEventListener("Tracker Ready", onReady);
13385
- onReady();
13428
+ window.addEventListener("Tracker Ready", onReady2);
13429
+ onReady2();
13386
13430
  });
13387
13431
  }
13388
13432
  function waitForIdentifyStage(stage, timeout, run, report) {
@@ -13427,28 +13471,63 @@ function observeIdentifyResult(stage, report, onTimeout) {
13427
13471
  }, 5e3);
13428
13472
  return { complete };
13429
13473
  }
13430
- const version = "1.1.8-alpha.0";
13474
+ const version = "1.1.8-alpha.1";
13431
13475
  const MIXPANEL_DISTINCT_ID_CACHE_KEY = "mp_distinct_id";
13476
+ const readinessSubscribers$1 = /* @__PURE__ */ new Set();
13477
+ let initializing = false;
13478
+ let initialization$2 = 0;
13479
+ let initializedConfig;
13480
+ function onReady$1(callback) {
13481
+ readinessSubscribers$1.add(callback);
13482
+ return () => {
13483
+ readinessSubscribers$1.delete(callback);
13484
+ };
13485
+ }
13432
13486
  const SDK_SUPER_PROPERTIES = {
13433
13487
  "Event Source": "sdk",
13434
13488
  "Reservamos Version": version
13435
13489
  };
13436
13490
  function init$2(mixpanelToken, debug = false, proxyUrl) {
13491
+ validateConfiguration(mixpanelToken, proxyUrl);
13492
+ const attempt = ++initialization$2;
13493
+ initializing = true;
13494
+ trackingLifecycle.beginInitialization();
13495
+ if (initializedConfig && window.mixpanel === mixpanel) {
13496
+ mixpanel.set_config({ debug });
13497
+ initializing = false;
13498
+ readinessSubscribers$1.forEach((notify) => notify());
13499
+ return Promise.resolve();
13500
+ }
13437
13501
  return new Promise((resolve) => {
13438
13502
  mixpanel.init(mixpanelToken, {
13439
13503
  debug,
13440
13504
  loaded: () => {
13505
+ if (attempt !== initialization$2) {
13506
+ resolve();
13507
+ return;
13508
+ }
13441
13509
  window.mixpanel = mixpanel;
13442
13510
  mixpanel.register({ ...SDK_SUPER_PROPERTIES });
13511
+ initializedConfig = { token: mixpanelToken, proxyUrl };
13512
+ initializing = false;
13513
+ readinessSubscribers$1.forEach((notify) => notify());
13443
13514
  resolve();
13444
13515
  },
13445
13516
  ...proxyUrl && { api_host: proxyUrl }
13446
13517
  });
13447
13518
  });
13448
13519
  }
13449
- function identify$1(userId, properties, report) {
13450
- mixpanel.identify(userId);
13451
- if (!updateCachedDistinctId(userId)) report == null ? void 0 : report("cache", "unavailable");
13520
+ function validateConfiguration(token, proxyUrl) {
13521
+ if (initializedConfig && window.mixpanel === mixpanel && (initializedConfig.token !== token || initializedConfig.proxyUrl !== proxyUrl)) {
13522
+ throw new Error(
13523
+ "Changing the Mixpanel project or proxy requires a new page session."
13524
+ );
13525
+ }
13526
+ }
13527
+ function identify$1(userId2, properties, report) {
13528
+ trackingLifecycle.identify(userId2);
13529
+ mixpanel.identify(userId2);
13530
+ if (!updateCachedDistinctId(userId2)) report == null ? void 0 : report("cache", "unavailable");
13452
13531
  if (!report) {
13453
13532
  mixpanel.people.set(properties);
13454
13533
  return;
@@ -13478,7 +13557,7 @@ function setPeopleProperties(properties) {
13478
13557
  mixpanel.people.set(properties);
13479
13558
  }
13480
13559
  function isReady() {
13481
- return window.mixpanel !== void 0;
13560
+ return !initializing && window.mixpanel !== void 0;
13482
13561
  }
13483
13562
  function track(eventName, properties) {
13484
13563
  if (!isReady()) {
@@ -13509,7 +13588,9 @@ function updateCachedDistinctId(distinctId) {
13509
13588
  }
13510
13589
  const mixpanelService = {
13511
13590
  init: init$2,
13591
+ validateConfiguration,
13512
13592
  isReady,
13593
+ onReady: onReady$1,
13513
13594
  track,
13514
13595
  identify: identify$1,
13515
13596
  attachProperty,
@@ -13520,6 +13601,18 @@ const DEFAULT_CACHE_NAME = "default_fingerprint_cache";
13520
13601
  const DEFAULT_CACHE_TIME_IN_DAYS = 7;
13521
13602
  const PROXY_QUERY_PARAM = "apiKey=<apiKey>&version=<version>&loaderVersion=<loaderVersion>";
13522
13603
  let fingerprintAgentReady = false;
13604
+ let initialization$1 = 0;
13605
+ const readinessSubscribers = /* @__PURE__ */ new Set();
13606
+ function onReady(notify) {
13607
+ readinessSubscribers.add(notify);
13608
+ return () => {
13609
+ readinessSubscribers.delete(notify);
13610
+ };
13611
+ }
13612
+ function invalidate() {
13613
+ initialization$1++;
13614
+ fingerprintAgentReady = false;
13615
+ }
13523
13616
  const getExpirationDate = (cacheTimeInDays) => {
13524
13617
  const currentDate = /* @__PURE__ */ new Date();
13525
13618
  const futureDate = new Date(
@@ -13565,7 +13658,8 @@ async function initFingerprint(apiKey, proxyUrl) {
13565
13658
  customEndpointArray.unshift(proxyUrl);
13566
13659
  customScriptEndpointArray.unshift(buildProxyUrl(proxyUrl));
13567
13660
  }
13568
- fingerprintAgentReady = false;
13661
+ invalidate();
13662
+ const attempt = initialization$1;
13569
13663
  window.fingerprintConfig = {};
13570
13664
  const client = new FpjsClient({
13571
13665
  loadOptions: {
@@ -13577,19 +13671,20 @@ async function initFingerprint(apiKey, proxyUrl) {
13577
13671
  window.fpClient = client;
13578
13672
  try {
13579
13673
  await client.init();
13580
- if (window.fpClient === client) {
13674
+ if (window.fpClient === client && attempt === initialization$1) {
13581
13675
  fingerprintAgentReady = true;
13676
+ readinessSubscribers.forEach((notify) => notify());
13582
13677
  }
13583
13678
  } catch (error) {
13584
- if (window.fpClient === client) {
13679
+ if (window.fpClient === client && attempt === initialization$1) {
13585
13680
  fingerprintAgentReady = false;
13586
13681
  }
13587
13682
  console.error("Error initializing identification service:", error);
13588
13683
  throw error;
13589
13684
  }
13590
13685
  }
13591
- async function getFingerprint(cacheOnly = false) {
13592
- return readFingerprint(cacheOnly);
13686
+ async function getFingerprint(cacheOnly = false, context) {
13687
+ return readFingerprint(cacheOnly, context);
13593
13688
  }
13594
13689
  function getFingerprintForIdentify(context) {
13595
13690
  return readFingerprint(false, context);
@@ -13605,8 +13700,8 @@ async function readFingerprint(cacheOnly, context) {
13605
13700
  const { visitorId } = await requestIdentification(false, context);
13606
13701
  return visitorId;
13607
13702
  }
13608
- async function identifyVisitor(ignoreCache = false) {
13609
- return requestIdentification(ignoreCache);
13703
+ async function identifyVisitor(ignoreCache = false, context) {
13704
+ return requestIdentification(ignoreCache, context);
13610
13705
  }
13611
13706
  async function requestIdentification(ignoreCache, context) {
13612
13707
  if (!isFingerprintReady()) {
@@ -13617,9 +13712,8 @@ async function requestIdentification(ignoreCache, context) {
13617
13712
  if (!context || context.isActive()) {
13618
13713
  try {
13619
13714
  setCachedFingerprint(result.visitorId);
13620
- } catch (error) {
13621
- if (!context) throw error;
13622
- context.report("cache", "unavailable");
13715
+ } catch {
13716
+ context == null ? void 0 : context.report("cache", "unavailable");
13623
13717
  }
13624
13718
  if (typeof result.visitorFound === "boolean") {
13625
13719
  try {
@@ -13652,8 +13746,168 @@ const fingerprintService = {
13652
13746
  getFingerprint,
13653
13747
  identifyVisitor,
13654
13748
  isFingerprintReady,
13749
+ onReady,
13750
+ invalidate,
13655
13751
  getCachedFingerprint
13656
13752
  };
13753
+ trackingLifecycle.onInitialization(invalidate);
13754
+ function createPendingWorkQueue(options) {
13755
+ const entries = /* @__PURE__ */ new Set();
13756
+ let bytes = 0;
13757
+ let active = 0;
13758
+ let draining = false;
13759
+ let unsubscribe;
13760
+ let timer;
13761
+ function diagnostic(entry, reason) {
13762
+ console.error("Tracking recovery diagnostic", {
13763
+ eventName: entry.eventName,
13764
+ stage: options.stage,
13765
+ reason
13766
+ });
13767
+ }
13768
+ function resolveForeground(entry) {
13769
+ var _a;
13770
+ (_a = entry.resolve) == null ? void 0 : _a.call(entry);
13771
+ entry.resolve = void 0;
13772
+ }
13773
+ function close(entry, reason) {
13774
+ if (entry.state === "closed") return;
13775
+ entry.state = "closed";
13776
+ entries.delete(entry);
13777
+ bytes -= entry.bytes;
13778
+ resolveForeground(entry);
13779
+ if (reason) diagnostic(entry, reason);
13780
+ }
13781
+ function schedule() {
13782
+ clearTimeout(timer);
13783
+ timer = void 0;
13784
+ if (entries.size === 0) {
13785
+ unsubscribe == null ? void 0 : unsubscribe();
13786
+ unsubscribe = void 0;
13787
+ return;
13788
+ }
13789
+ let next = Infinity;
13790
+ for (const entry of entries) {
13791
+ next = Math.min(next, entry.deadline);
13792
+ if (entry.resolve) next = Math.min(next, entry.foregroundDeadline);
13793
+ }
13794
+ timer = setTimeout(drain, Math.max(0, next - Date.now()));
13795
+ }
13796
+ function drain() {
13797
+ if (draining) return;
13798
+ draining = true;
13799
+ try {
13800
+ for (const entry of entries) {
13801
+ if (!entry.isCurrent()) close(entry, "identity_changed");
13802
+ else if (Date.now() >= entry.deadline) close(entry, "timeout");
13803
+ else if (entry.resolve && Date.now() >= entry.foregroundDeadline) {
13804
+ resolveForeground(entry);
13805
+ }
13806
+ }
13807
+ for (const entry of entries) {
13808
+ if (active >= options.maxActive || !options.isReady()) break;
13809
+ if (entry.state !== "waiting") continue;
13810
+ entry.state = "active";
13811
+ active++;
13812
+ const isActive = () => entry.state === "active" && Date.now() < entry.deadline && entry.isCurrent();
13813
+ const finish = (failed = false) => {
13814
+ if (failed && isActive()) diagnostic(entry, "failed");
13815
+ close(entry);
13816
+ active--;
13817
+ drain();
13818
+ };
13819
+ try {
13820
+ void Promise.resolve(entry.run(isActive)).then(
13821
+ () => finish(),
13822
+ () => finish(true)
13823
+ );
13824
+ } catch {
13825
+ finish(true);
13826
+ }
13827
+ }
13828
+ } finally {
13829
+ draining = false;
13830
+ schedule();
13831
+ }
13832
+ }
13833
+ function enqueue(work) {
13834
+ if (work.bytes > options.maxBytes) {
13835
+ diagnostic(work, "capacity");
13836
+ return Promise.resolve();
13837
+ }
13838
+ while (entries.size >= options.maxEntries || bytes + work.bytes > options.maxBytes) {
13839
+ const oldest = [...entries].find((entry) => entry.state === "waiting");
13840
+ if (!oldest) {
13841
+ diagnostic(work, "capacity");
13842
+ return Promise.resolve();
13843
+ }
13844
+ close(oldest, "capacity");
13845
+ }
13846
+ return new Promise((resolve) => {
13847
+ const entry = {
13848
+ ...work,
13849
+ state: "waiting",
13850
+ deadline: Date.now() + options.lifetime,
13851
+ foregroundDeadline: Date.now() + options.wait,
13852
+ resolve
13853
+ };
13854
+ entries.add(entry);
13855
+ bytes += entry.bytes;
13856
+ unsubscribe ?? (unsubscribe = options.subscribe(drain));
13857
+ drain();
13858
+ });
13859
+ }
13860
+ return { enqueue };
13861
+ }
13862
+ const observations = createPendingWorkQueue({
13863
+ isReady: () => fingerprintService.isFingerprintReady(),
13864
+ subscribe(notify) {
13865
+ const stopReady = fingerprintService.onReady(notify);
13866
+ const stopIdentity = trackingLifecycle.onChange(notify);
13867
+ return () => {
13868
+ stopReady();
13869
+ stopIdentity();
13870
+ };
13871
+ },
13872
+ maxEntries: 100,
13873
+ maxBytes: 1024 * 1024,
13874
+ maxActive: 3,
13875
+ lifetime: 1e4,
13876
+ wait: 0,
13877
+ stage: "fingerprint"
13878
+ });
13879
+ function deferBotDetection(eventName, distinctId, isCurrent) {
13880
+ void observations.enqueue({
13881
+ eventName,
13882
+ bytes: new Blob([eventName, distinctId ?? ""]).size,
13883
+ isCurrent,
13884
+ async run(isActive) {
13885
+ let stage = "fingerprint";
13886
+ try {
13887
+ const identification = await fingerprintService.identifyVisitor(true, {
13888
+ isActive,
13889
+ report: () => void 0
13890
+ });
13891
+ if (!isActive() || !identification.requestId) return;
13892
+ stage = "relay";
13893
+ await botDetectionRelayService.relay({
13894
+ requestId: identification.requestId,
13895
+ visitorId: identification.visitorId,
13896
+ ...distinctId && { distinctId },
13897
+ eventName
13898
+ });
13899
+ } catch {
13900
+ if (isActive()) {
13901
+ console.error("Bot Detection diagnostic", {
13902
+ eventName,
13903
+ stage,
13904
+ reason: "failed"
13905
+ });
13906
+ }
13907
+ }
13908
+ }
13909
+ });
13910
+ }
13657
13911
  let environment;
13658
13912
  let appName;
13659
13913
  const origin = window.location.origin;
@@ -13792,7 +14046,7 @@ const tripSchema = z.object({
13792
14046
  "Departure Origin Terminal": stringField("Departure Origin Terminal"),
13793
14047
  "Departure Price": numberField("Departure Price"),
13794
14048
  "Departure Route": stringField("Departure Route"),
13795
- "Departure Stops": intField("Departure Stops"),
14049
+ "Departure Stops": z.number().int(),
13796
14050
  "Departure Time": dateField("Departure Time"),
13797
14051
  "Departure Transport Type": stringField("Departure Transport Type"),
13798
14052
  "Departure Transporter": stringField("Departure Transporter"),
@@ -13806,7 +14060,7 @@ const tripSchema = z.object({
13806
14060
  "Return Origin Terminal": stringField("Return Origin Terminal").optional(),
13807
14061
  "Return Price": numberField("Return Price").optional(),
13808
14062
  "Return Route": stringField("Return Route").optional(),
13809
- "Return Stops": intField("Return Stops").optional(),
14063
+ "Return Stops": z.number().int().optional(),
13810
14064
  "Return Time": dateField("Return Time").optional(),
13811
14065
  "Return Transport Type": stringField("Return Transport Type").optional(),
13812
14066
  "Return Transporter": stringField("Return Transporter").optional(),
@@ -14071,6 +14325,7 @@ const validatorService = {
14071
14325
  parseIdentifyProps,
14072
14326
  validateProps
14073
14327
  };
14328
+ let initialization = 0;
14074
14329
  function onLoaded() {
14075
14330
  window.dispatchEvent(new CustomEvent("Tracker Ready"));
14076
14331
  }
@@ -14085,19 +14340,30 @@ async function init$1(config) {
14085
14340
  identifyProxyUrl,
14086
14341
  appName: appName2
14087
14342
  } = config;
14343
+ mixpanelService.validateConfiguration(mixpanelToken, mixpanelProxyUrl);
14344
+ const attempt = ++initialization;
14345
+ const isCurrent = () => attempt === initialization;
14088
14346
  await mixpanelService.init(mixpanelToken, debug, mixpanelProxyUrl);
14347
+ if (!isCurrent()) return;
14089
14348
  configService.setEnvironment(isSandbox ? "sandbox" : "prod");
14090
14349
  if (appName2) {
14091
14350
  configService.setAppName(appName2);
14092
14351
  }
14093
14352
  a$1.setConfig(configService.getCoreAPIConfig());
14094
14353
  onLoaded();
14354
+ if (!isCurrent()) return;
14095
14355
  await Promise.all([
14096
14356
  initializeOptionalStage(
14097
14357
  "fingerprint",
14098
- () => fingerprintService.initFingerprint(identificationKey, identifyProxyUrl)
14358
+ () => isCurrent() ? fingerprintService.initFingerprint(
14359
+ identificationKey,
14360
+ identifyProxyUrl
14361
+ ) : Promise.resolve()
14099
14362
  ),
14100
- initializeOptionalStage("geolocation", () => geolocationService.init())
14363
+ initializeOptionalStage(
14364
+ "geolocation",
14365
+ () => isCurrent() ? geolocationService.init() : Promise.resolve()
14366
+ )
14101
14367
  ]);
14102
14368
  }
14103
14369
  function initializeOptionalStage(stage, initialize) {
@@ -14323,6 +14589,20 @@ const geolocationService = {
14323
14589
  getCoordinates,
14324
14590
  getGeolocationSource
14325
14591
  };
14592
+ function snapshotEventData(value) {
14593
+ if (Array.isArray(value))
14594
+ return value.map((item) => snapshotEventData(item));
14595
+ if (value instanceof Date) return new Date(value.getTime());
14596
+ if (value !== null && typeof value === "object") {
14597
+ return Object.fromEntries(
14598
+ Object.entries(value).map(([key, item]) => [
14599
+ key,
14600
+ snapshotEventData(item)
14601
+ ])
14602
+ );
14603
+ }
14604
+ return value;
14605
+ }
14326
14606
  const FP_TRIGGER_EVENTS = ["Search", "View Results"];
14327
14607
  const EXTRA_UTM_FIELDS = {
14328
14608
  utm_brand: "UTM Brand",
@@ -14377,15 +14657,17 @@ async function tryTrackEvent(trackEventCallback, eventName = "Track Event Error"
14377
14657
  const ready = await new Promise((resolve) => {
14378
14658
  const finish = (isReady2) => {
14379
14659
  clearTimeout(timer);
14380
- window.removeEventListener("Tracker Ready", onReady);
14660
+ window.removeEventListener("Tracker Ready", onReady2);
14661
+ unsubscribe();
14381
14662
  resolve(isReady2);
14382
14663
  };
14383
- const onReady = () => {
14664
+ const onReady2 = () => {
14384
14665
  if (mixpanelService.isReady()) finish(true);
14385
14666
  };
14386
14667
  const timer = setTimeout(() => finish(mixpanelService.isReady()), 5e3);
14387
- window.addEventListener("Tracker Ready", onReady);
14388
- onReady();
14668
+ const unsubscribe = mixpanelService.onReady(onReady2);
14669
+ window.addEventListener("Tracker Ready", onReady2);
14670
+ onReady2();
14389
14671
  });
14390
14672
  if (!ready) {
14391
14673
  console.error("Tracking diagnostic", {
@@ -14406,28 +14688,94 @@ async function tryTrackEvent(trackEventCallback, eventName = "Track Event Error"
14406
14688
  });
14407
14689
  }
14408
14690
  }
14691
+ const pendingEvents = createPendingWorkQueue({
14692
+ isReady: () => mixpanelService.isReady(),
14693
+ subscribe(notify) {
14694
+ const stopReady = mixpanelService.onReady(notify);
14695
+ const stopIdentity = trackingLifecycle.onChange(notify);
14696
+ window.addEventListener("Tracker Ready", notify);
14697
+ return () => {
14698
+ stopReady();
14699
+ stopIdentity();
14700
+ window.removeEventListener("Tracker Ready", notify);
14701
+ };
14702
+ },
14703
+ maxEntries: 100,
14704
+ maxBytes: 1024 * 1024,
14705
+ maxActive: 100,
14706
+ lifetime: 6e4,
14707
+ wait: 5e3,
14708
+ stage: "readiness"
14709
+ });
14409
14710
  function trackEvent(eventName, eventProperties, meta = {}) {
14410
- return tryTrackEvent(
14411
- () => submitEvent(eventName, eventProperties, meta),
14412
- eventName
14413
- );
14711
+ const isCurrent = trackingLifecycle.capture();
14712
+ const trackingParams = extractTrackingParams();
14713
+ if (mixpanelService.isReady()) {
14714
+ return submitEvent(
14715
+ eventName,
14716
+ eventProperties,
14717
+ meta,
14718
+ isCurrent,
14719
+ trackingParams
14720
+ );
14721
+ }
14722
+ try {
14723
+ validatorService.parseEventProps(eventName, eventProperties);
14724
+ } catch (error) {
14725
+ trackEventError(eventName, error, eventProperties);
14726
+ return Promise.resolve();
14727
+ }
14728
+ let snapshot2;
14729
+ let bytes;
14730
+ try {
14731
+ const serialized = JSON.stringify(
14732
+ { eventName, eventProperties, meta, trackingParams },
14733
+ (_key, value) => {
14734
+ if (typeof value === "function" || typeof value === "symbol")
14735
+ throw new Error();
14736
+ return value === void 0 ? null : value;
14737
+ }
14738
+ );
14739
+ bytes = new Blob([serialized]).size;
14740
+ if (bytes > 1024 * 1024) throw new Error();
14741
+ snapshot2 = snapshotEventData({ eventProperties, meta });
14742
+ } catch {
14743
+ console.error("Tracking recovery diagnostic", {
14744
+ eventName,
14745
+ stage: "readiness",
14746
+ reason: "snapshot_unavailable"
14747
+ });
14748
+ return Promise.resolve();
14749
+ }
14750
+ return pendingEvents.enqueue({
14751
+ eventName,
14752
+ bytes,
14753
+ isCurrent,
14754
+ run: (isActive) => submitEvent(
14755
+ eventName,
14756
+ snapshot2.eventProperties,
14757
+ snapshot2.meta,
14758
+ isActive,
14759
+ trackingParams
14760
+ )
14761
+ });
14414
14762
  }
14415
- async function submitEvent(eventName, eventProperties, meta) {
14763
+ async function submitEvent(eventName, eventProperties, meta, isCurrent, trackingParams) {
14764
+ const observationContext = trackingLifecycle.capture();
14416
14765
  try {
14417
14766
  validatorService.parseEventProps(eventName, eventProperties);
14418
14767
  const distinctId = mixpanelService.getMixpanelDistinctId();
14419
14768
  const botDetectionEnabled = botDetectionRelayService.isEnabledFor(eventName);
14420
14769
  let fingerprint = "";
14421
- if (botDetectionEnabled) {
14770
+ if (botDetectionEnabled || FP_TRIGGER_EVENTS.includes(eventName)) {
14422
14771
  try {
14423
14772
  fingerprint = fingerprintService.getCachedFingerprint() ?? "";
14424
14773
  } catch (error) {
14425
14774
  console.error("Error reading cached fingerprint:", error);
14426
14775
  }
14427
14776
  } else {
14428
- const cacheOnly = !FP_TRIGGER_EVENTS.includes(eventName);
14429
14777
  try {
14430
- fingerprint = await fingerprintService.getFingerprint(cacheOnly);
14778
+ fingerprint = await fingerprintService.getFingerprint(true);
14431
14779
  } catch {
14432
14780
  console.error("Tracking diagnostic", {
14433
14781
  eventName,
@@ -14449,7 +14797,6 @@ async function submitEvent(eventName, eventProperties, meta) {
14449
14797
  const defaultProperties = {
14450
14798
  "User Fingerprint": fingerprint
14451
14799
  };
14452
- const trackingParams = extractTrackingParams();
14453
14800
  const simplifiedData = flattenEventData(eventProperties);
14454
14801
  const properties = {
14455
14802
  ...defaultProperties,
@@ -14458,28 +14805,40 @@ async function submitEvent(eventName, eventProperties, meta) {
14458
14805
  ...defaultCoordinates,
14459
14806
  ...meta
14460
14807
  };
14461
- mixpanelService.track(eventName, properties);
14808
+ if (!isCurrent()) return;
14809
+ try {
14810
+ mixpanelService.track(eventName, properties);
14811
+ } catch {
14812
+ console.error("Tracking diagnostic", {
14813
+ eventName,
14814
+ stage: "submission",
14815
+ reason: "uncertain"
14816
+ });
14817
+ return;
14818
+ }
14462
14819
  if (botDetectionEnabled) {
14463
- void identifyAndRelayFingerprint(eventName, distinctId);
14820
+ deferBotDetection(eventName, distinctId, observationContext);
14821
+ } else if (FP_TRIGGER_EVENTS.includes(eventName)) {
14822
+ void refreshFingerprint(eventName, observationContext);
14464
14823
  }
14465
14824
  } catch (error) {
14466
14825
  console.error(`Error tracking event '${eventName}':`, error);
14467
14826
  trackEventError(eventName, error, eventProperties);
14468
14827
  }
14469
14828
  }
14470
- async function identifyAndRelayFingerprint(eventName, distinctId) {
14829
+ async function refreshFingerprint(eventName, isCurrent) {
14830
+ const deadline = Date.now() + 1e4;
14471
14831
  try {
14472
- if (!fingerprintService.isFingerprintReady()) return;
14473
- const identification = await fingerprintService.identifyVisitor(true);
14474
- if (!identification.requestId) return;
14475
- await botDetectionRelayService.relay({
14476
- requestId: identification.requestId,
14477
- visitorId: identification.visitorId,
14478
- ...distinctId && { distinctId },
14479
- eventName
14832
+ await fingerprintService.getFingerprint(false, {
14833
+ isActive: () => isCurrent() && Date.now() < deadline,
14834
+ report: () => void 0
14835
+ });
14836
+ } catch {
14837
+ console.error("Tracking diagnostic", {
14838
+ eventName,
14839
+ stage: "fingerprint",
14840
+ reason: "failed"
14480
14841
  });
14481
- } catch (error) {
14482
- console.error(`Error running Bot Detection for '${eventName}':`, error);
14483
14842
  }
14484
14843
  }
14485
14844
  function extractTrackingParams() {
@@ -14616,7 +14975,7 @@ function mapProperties(properties) {
14616
14975
  );
14617
14976
  return { ...parsedProperties, ...additionalProperties };
14618
14977
  }
14619
- const identifyWithLocation = async (userId, properties, report) => {
14978
+ const identifyWithLocation = async (userId2, properties, report) => {
14620
14979
  var _a, _b, _c;
14621
14980
  let observer;
14622
14981
  try {
@@ -14653,7 +15012,7 @@ const identifyWithLocation = async (userId, properties, report) => {
14653
15012
  body: JSON.stringify({
14654
15013
  profile_params: {
14655
15014
  ...properties,
14656
- distinct_id: userId
15015
+ distinct_id: userId2
14657
15016
  }
14658
15017
  })
14659
15018
  }
@@ -14667,13 +15026,13 @@ const identifyWithLocation = async (userId, properties, report) => {
14667
15026
  else report("datalake", "failed");
14668
15027
  }
14669
15028
  };
14670
- async function identify(userId, properties = {}) {
15029
+ async function identify(userId2, properties = {}) {
14671
15030
  const report = createIdentifyReporter();
14672
15031
  if (!await waitForIdentifyReady(report)) return;
14673
15032
  try {
14674
15033
  try {
14675
15034
  validatorService.parseIdentifyProps(properties);
14676
- if (!userId) {
15035
+ if (!userId2) {
14677
15036
  report("validation", "invalid_input");
14678
15037
  return;
14679
15038
  }
@@ -14692,7 +15051,7 @@ async function identify(userId, properties = {}) {
14692
15051
  }
14693
15052
  const mappedProps = mapProperties(properties);
14694
15053
  try {
14695
- mixpanelService.identify(userId, mappedProps, report);
15054
+ mixpanelService.identify(userId2, mappedProps, report);
14696
15055
  } catch {
14697
15056
  report("mixpanel", "failed");
14698
15057
  }
@@ -14712,7 +15071,7 @@ async function identify(userId, properties = {}) {
14712
15071
  } catch {
14713
15072
  report("mixpanel", "failed");
14714
15073
  } finally {
14715
- void identifyWithLocation(userId, properties, report);
15074
+ void identifyWithLocation(userId2, properties, report);
14716
15075
  }
14717
15076
  }
14718
15077
  z.object({