@tracelog/lib 2.1.0-rc.74.5 → 2.1.1-rc.75.2

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.

Potentially problematic release.


This version of @tracelog/lib might be problematic. Click here for more details.

@@ -720,7 +720,7 @@ var init_performance_constants = __esm({
720
720
  var version;
721
721
  var init_package = __esm({
722
722
  "package.json"() {
723
- version = "2.1.0";
723
+ version = "2.1.1";
724
724
  }
725
725
  });
726
726
 
@@ -829,6 +829,61 @@ var init_mode_utils = __esm({
829
829
  }
830
830
  });
831
831
 
832
+ // src/utils/browser/referrer.utils.ts
833
+ var COMPOUND_TLDS, getRootDomain, isSameDomain, getExternalReferrer;
834
+ var init_referrer_utils = __esm({
835
+ "src/utils/browser/referrer.utils.ts"() {
836
+ init_logging_utils();
837
+ COMPOUND_TLDS = [
838
+ "co.uk",
839
+ "org.uk",
840
+ "com.au",
841
+ "net.au",
842
+ "com.br",
843
+ "co.nz",
844
+ "co.jp",
845
+ "com.mx",
846
+ "co.in",
847
+ "com.cn",
848
+ "co.za"
849
+ ];
850
+ getRootDomain = (hostname) => {
851
+ const parts = hostname.toLowerCase().split(".");
852
+ if (parts.length <= 2) {
853
+ return hostname.toLowerCase();
854
+ }
855
+ const lastTwo = parts.slice(-2).join(".");
856
+ if (COMPOUND_TLDS.includes(lastTwo)) {
857
+ return parts.slice(-3).join(".");
858
+ }
859
+ return parts.slice(-2).join(".");
860
+ };
861
+ isSameDomain = (hostname1, hostname2) => {
862
+ if (hostname1 === hostname2) {
863
+ return true;
864
+ }
865
+ return getRootDomain(hostname1) === getRootDomain(hostname2);
866
+ };
867
+ getExternalReferrer = () => {
868
+ const referrer = document.referrer;
869
+ if (!referrer) {
870
+ return "Direct";
871
+ }
872
+ try {
873
+ const referrerHostname = new URL(referrer).hostname.toLowerCase();
874
+ const currentHostname = window.location.hostname.toLowerCase();
875
+ if (isSameDomain(referrerHostname, currentHostname)) {
876
+ return "Direct";
877
+ }
878
+ return referrer;
879
+ } catch (error) {
880
+ log("debug", "Failed to parse referrer URL, using raw value", { error, data: { referrer } });
881
+ return referrer;
882
+ }
883
+ };
884
+ }
885
+ });
886
+
832
887
  // src/utils/browser/utm-params.utils.ts
833
888
  var getUTMParameters;
834
889
  var init_utm_params_utils = __esm({
@@ -855,6 +910,7 @@ var init_browser = __esm({
855
910
  "src/utils/browser/index.ts"() {
856
911
  init_device_detector_utils();
857
912
  init_mode_utils();
913
+ init_referrer_utils();
858
914
  init_utm_params_utils();
859
915
  }
860
916
  });
@@ -3506,7 +3562,6 @@ var init_event_manager = __esm({
3506
3562
  return queue;
3507
3563
  }
3508
3564
  buildEventPayload(data) {
3509
- const isSessionStart = data.type === "session_start" /* SESSION_START */;
3510
3565
  const currentPageUrl = data.page_url ?? this.get("pageUrl");
3511
3566
  const timestamp = this.timeManager.now();
3512
3567
  const validation = this.timeManager.validateTimestamp(timestamp);
@@ -3515,12 +3570,14 @@ var init_event_manager = __esm({
3515
3570
  data: { type: data.type, error: validation.error }
3516
3571
  });
3517
3572
  }
3573
+ const sessionReferrer = this.get("sessionReferrer");
3574
+ const sessionUtm = this.get("sessionUtm");
3518
3575
  let payload = {
3519
3576
  id: generateEventId(),
3520
3577
  type: data.type,
3521
3578
  page_url: currentPageUrl,
3522
3579
  timestamp,
3523
- ...isSessionStart && { referrer: this.getExternalReferrer() },
3580
+ ...sessionReferrer && { referrer: sessionReferrer },
3524
3581
  ...data.from_page_url && { from_page_url: data.from_page_url },
3525
3582
  ...data.scroll_data && { scroll_data: data.scroll_data },
3526
3583
  ...data.click_data && { click_data: data.click_data },
@@ -3529,7 +3586,7 @@ var init_event_manager = __esm({
3529
3586
  ...data.error_data && { error_data: data.error_data },
3530
3587
  ...data.viewport_data && { viewport_data: data.viewport_data },
3531
3588
  ...data.page_view && { page_view: data.page_view },
3532
- ...isSessionStart && getUTMParameters() && { utm: getUTMParameters() }
3589
+ ...sessionUtm && { utm: sessionUtm }
3533
3590
  };
3534
3591
  const collectApiUrls = this.get("collectApiUrls");
3535
3592
  const hasCustomBackend = Boolean(collectApiUrls?.custom);
@@ -3882,102 +3939,6 @@ var init_event_manager = __esm({
3882
3939
  log("warn", "Failed to cleanup expired session counts", { error });
3883
3940
  }
3884
3941
  }
3885
- /**
3886
- * Returns the referrer if it's external, or 'Direct' if internal/empty.
3887
- *
3888
- * **Purpose**: Filter out internal referrers (same domain) to ensure
3889
- * accurate traffic source attribution. Internal referrers occur when:
3890
- * - Session expires and user navigates within the same site
3891
- * - User opens new tab from an internal link
3892
- * - Page refresh after session timeout
3893
- *
3894
- * **Logic**:
3895
- * - Empty referrer → 'Direct'
3896
- * - Referrer from same domain or subdomain → 'Direct' (internal navigation)
3897
- * - External referrer → Returns original referrer
3898
- *
3899
- * **Subdomain Detection**:
3900
- * - `www.example.com` → `example.com` ✓ (internal)
3901
- * - `blog.example.com` → `example.com` ✓ (internal)
3902
- * - `example.com` → `www.example.com` ✓ (internal)
3903
- *
3904
- * @returns External referrer URL or 'Direct'
3905
- *
3906
- * @internal
3907
- */
3908
- getExternalReferrer() {
3909
- const referrer = document.referrer;
3910
- if (!referrer) {
3911
- return "Direct";
3912
- }
3913
- try {
3914
- const referrerHostname = new URL(referrer).hostname.toLowerCase();
3915
- const currentHostname = window.location.hostname.toLowerCase();
3916
- if (this.isSameDomain(referrerHostname, currentHostname)) {
3917
- return "Direct";
3918
- }
3919
- return referrer;
3920
- } catch (error) {
3921
- log("debug", "Failed to parse referrer URL, using raw value", { error, data: { referrer } });
3922
- return referrer;
3923
- }
3924
- }
3925
- /**
3926
- * Checks if two hostnames belong to the same domain (including subdomains).
3927
- * Extracts root domain and compares to handle cross-subdomain navigation.
3928
- *
3929
- * @example
3930
- * isSameDomain('www.example.com', 'example.com') // true
3931
- * isSameDomain('app.example.com', 'www.example.com') // true
3932
- * isSameDomain('example.co.uk', 'app.example.co.uk') // true
3933
- *
3934
- * @param hostname1 - First hostname (e.g., 'www.example.com')
3935
- * @param hostname2 - Second hostname (e.g., 'app.example.com')
3936
- * @returns true if same root domain
3937
- *
3938
- * @internal
3939
- */
3940
- isSameDomain(hostname1, hostname2) {
3941
- if (hostname1 === hostname2) {
3942
- return true;
3943
- }
3944
- return this.getRootDomain(hostname1) === this.getRootDomain(hostname2);
3945
- }
3946
- /**
3947
- * Extracts the root (registrable) domain from a hostname.
3948
- * Handles both standard TLDs (.com, .org) and compound TLDs (.co.uk, .com.br).
3949
- *
3950
- * @example
3951
- * getRootDomain('www.example.com') // 'example.com'
3952
- * getRootDomain('app.blog.example.com') // 'example.com'
3953
- * getRootDomain('shop.example.co.uk') // 'example.co.uk'
3954
- *
3955
- * @internal
3956
- */
3957
- getRootDomain(hostname) {
3958
- const parts = hostname.toLowerCase().split(".");
3959
- if (parts.length <= 2) {
3960
- return hostname.toLowerCase();
3961
- }
3962
- const compoundTlds = [
3963
- "co.uk",
3964
- "org.uk",
3965
- "com.au",
3966
- "net.au",
3967
- "com.br",
3968
- "co.nz",
3969
- "co.jp",
3970
- "com.mx",
3971
- "co.in",
3972
- "com.cn",
3973
- "co.za"
3974
- ];
3975
- const lastTwo = parts.slice(-2).join(".");
3976
- if (compoundTlds.includes(lastTwo)) {
3977
- return parts.slice(-3).join(".");
3978
- }
3979
- return parts.slice(-2).join(".");
3980
- }
3981
3942
  /**
3982
3943
  * Persists current session event counts to localStorage (debounced).
3983
3944
  *
@@ -4154,10 +4115,12 @@ var init_session_manager = __esm({
4154
4115
  }
4155
4116
  return storedSession.id;
4156
4117
  }
4157
- persistSession(sessionId, lastActivity = Date.now()) {
4118
+ persistSession(sessionId, lastActivity = Date.now(), referrer, utm) {
4158
4119
  this.saveStoredSession({
4159
4120
  id: sessionId,
4160
- lastActivity
4121
+ lastActivity,
4122
+ ...referrer && { referrer },
4123
+ ...utm && { utm }
4161
4124
  });
4162
4125
  }
4163
4126
  clearStoredSession() {
@@ -4249,17 +4212,31 @@ var init_session_manager = __esm({
4249
4212
  }
4250
4213
  const recoveredSessionId = this.recoverSession();
4251
4214
  const sessionId = recoveredSessionId ?? this.generateSessionId();
4215
+ let sessionReferrer;
4216
+ let sessionUtm;
4217
+ if (recoveredSessionId) {
4218
+ const storedSession = this.loadStoredSession();
4219
+ sessionReferrer = storedSession?.referrer ?? getExternalReferrer();
4220
+ sessionUtm = storedSession?.utm ?? getUTMParameters();
4221
+ } else {
4222
+ sessionReferrer = getExternalReferrer();
4223
+ sessionUtm = getUTMParameters();
4224
+ }
4252
4225
  log("debug", "Session tracking initialized", {
4253
4226
  data: {
4254
4227
  sessionId,
4255
4228
  wasRecovered: !!recoveredSessionId,
4256
- willEmitSessionStart: true
4229
+ willEmitSessionStart: true,
4230
+ sessionReferrer,
4231
+ hasUtm: !!sessionUtm
4257
4232
  }
4258
4233
  });
4259
4234
  this.isTracking = true;
4260
4235
  try {
4261
4236
  this.set("sessionId", sessionId);
4262
- this.persistSession(sessionId);
4237
+ this.set("sessionReferrer", sessionReferrer);
4238
+ this.set("sessionUtm", sessionUtm);
4239
+ this.persistSession(sessionId, Date.now(), sessionReferrer, sessionUtm);
4263
4240
  this.initCrossTabSync();
4264
4241
  this.shareSession(sessionId);
4265
4242
  log("debug", "Emitting SESSION_START event", {
@@ -4295,7 +4272,7 @@ var init_session_manager = __esm({
4295
4272
  this.setupSessionTimeout();
4296
4273
  const sessionId = this.get("sessionId");
4297
4274
  if (sessionId) {
4298
- this.persistSession(sessionId);
4275
+ this.persistSession(sessionId, Date.now(), this.get("sessionReferrer"), this.get("sessionUtm"));
4299
4276
  }
4300
4277
  }
4301
4278
  clearSessionTimeout() {
@@ -4350,6 +4327,8 @@ var init_session_manager = __esm({
4350
4327
  this.clearStoredSession();
4351
4328
  this.set("sessionId", null);
4352
4329
  this.set("hasStartSession", false);
4330
+ this.set("sessionReferrer", void 0);
4331
+ this.set("sessionUtm", void 0);
4353
4332
  this.isTracking = false;
4354
4333
  }
4355
4334
  /**