@datalyr/web 1.0.0 → 1.0.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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @datalyr/web v1.0.0
2
+ * @datalyr/web v1.0.1
3
3
  * Datalyr Web SDK - Modern attribution tracking for web applications
4
4
  * (c) 2025 Datalyr Inc.
5
5
  * Released under the MIT License
@@ -807,9 +807,36 @@ class SessionManager {
807
807
  class AttributionManager {
808
808
  constructor(options = {}) {
809
809
  this.UTM_PARAMS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
810
- this.CLICK_IDS = ['fbclid', 'gclid', 'ttclid', 'msclkid', 'twclid', 'li_fat_id', 'sclid', 'dclid', 'epik'];
810
+ // Updated to match dl.js - includes ALL ad platform click IDs
811
+ this.CLICK_IDS = [
812
+ 'fbclid', // Facebook/Meta
813
+ 'gclid', // Google Ads
814
+ 'gbraid', // Google Ads (iOS)
815
+ 'wbraid', // Google Ads (web)
816
+ 'ttclid', // TikTok
817
+ 'msclkid', // Microsoft/Bing
818
+ 'twclid', // Twitter/X
819
+ 'li_fat_id', // LinkedIn
820
+ 'sclid', // Snapchat
821
+ 'dclid', // Google Display/DoubleClick
822
+ 'epik', // Pinterest
823
+ 'rdt_cid', // Reddit
824
+ 'obclid', // Outbrain
825
+ 'irclid', // Impact Radius
826
+ 'ko_click_id' // Klaviyo
827
+ ];
828
+ // Default tracked params matching dl.js
829
+ this.DEFAULT_TRACKED_PARAMS = [
830
+ 'lyr', // Datalyr partner tracking
831
+ 'ref', // Generic referral
832
+ 'source', // Generic source (non-UTM)
833
+ 'campaign', // Generic campaign (non-UTM)
834
+ 'medium', // Generic medium (non-UTM)
835
+ 'gad_source' // Google Ads source parameter
836
+ ];
811
837
  this.attributionWindow = options.attributionWindow || 30 * 24 * 60 * 60 * 1000; // 30 days
812
- this.trackedParams = options.trackedParams || [];
838
+ // Merge default tracked params with user-provided ones
839
+ this.trackedParams = [...this.DEFAULT_TRACKED_PARAMS, ...(options.trackedParams || [])];
813
840
  }
814
841
  /**
815
842
  * Capture current attribution from URL
@@ -896,9 +923,9 @@ class AttributionManager {
896
923
  const touchpoint = {
897
924
  timestamp: Date.now(),
898
925
  sessionId,
899
- source: attribution.source,
900
- medium: attribution.medium,
901
- campaign: attribution.campaign
926
+ source: attribution.source || undefined,
927
+ medium: attribution.medium || undefined,
928
+ campaign: attribution.campaign || undefined
902
929
  };
903
930
  journey.push(touchpoint);
904
931
  // Keep last 30 touchpoints
@@ -1070,7 +1097,6 @@ class EventQueue {
1070
1097
  this.recentEventIds = new Set();
1071
1098
  this.MAX_RECENT_EVENT_IDS = 1000;
1072
1099
  this.OFFLINE_QUEUE_KEY = 'dl_offline_queue';
1073
- this.currentEndpointIndex = 0;
1074
1100
  this.config = {
1075
1101
  batchSize: config.batchSize || 10,
1076
1102
  flushInterval: config.flushInterval || 5000,
@@ -1131,7 +1157,10 @@ class EventQueue {
1131
1157
  const toDelete = this.recentEventIds.size - this.MAX_RECENT_EVENT_IDS;
1132
1158
  const iterator = this.recentEventIds.values();
1133
1159
  for (let i = 0; i < toDelete; i++) {
1134
- this.recentEventIds.delete(iterator.next().value);
1160
+ const next = iterator.next();
1161
+ if (!next.done) {
1162
+ this.recentEventIds.delete(next.value);
1163
+ }
1135
1164
  }
1136
1165
  }
1137
1166
  return false;
@@ -1242,7 +1271,6 @@ class EventQueue {
1242
1271
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1243
1272
  }
1244
1273
  this.log(`Batch sent successfully to ${currentEndpoint}: ${events.length} events`);
1245
- this.currentEndpointIndex = 0; // Reset to primary on success
1246
1274
  }
1247
1275
  catch (error) {
1248
1276
  // Try next fallback endpoint if available
@@ -2056,8 +2084,8 @@ class ContainerManager {
2056
2084
  document.head.appendChild(script);
2057
2085
  // Initialize gtag
2058
2086
  window.dataLayer = window.dataLayer || [];
2059
- function gtag() {
2060
- window.dataLayer.push(arguments);
2087
+ function gtag(...args) {
2088
+ window.dataLayer.push(args);
2061
2089
  }
2062
2090
  window.gtag = gtag;
2063
2091
  gtag('js', new Date());
@@ -2076,7 +2104,7 @@ class ContainerManager {
2076
2104
  initializeTikTokPixel(config) {
2077
2105
  try {
2078
2106
  // Load TikTok Pixel script
2079
- (function (w, d, t) {
2107
+ (function (w, _d, t) {
2080
2108
  w.TiktokAnalyticsObject = t;
2081
2109
  var ttq = w[t] = w[t] || [];
2082
2110
  ttq.methods = ['page', 'track', 'identify', 'instances', 'debug', 'on', 'off', 'once', 'ready', 'alias', 'group', 'enableCookie', 'disableCookie'];
@@ -2093,6 +2121,7 @@ class ContainerManager {
2093
2121
  return e;
2094
2122
  };
2095
2123
  ttq.load = function (e, n) {
2124
+ var _a;
2096
2125
  var i = 'https://analytics.tiktok.com/i18n/pixel/events.js';
2097
2126
  ttq._i = ttq._i || {};
2098
2127
  ttq._i[e] = [];
@@ -2103,7 +2132,7 @@ class ContainerManager {
2103
2132
  o.async = true;
2104
2133
  o.src = i + '?sdkid=' + e + '&lib=' + t;
2105
2134
  var a = document.getElementsByTagName('script')[0];
2106
- a.parentNode.insertBefore(o, a);
2135
+ (_a = a.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(o, a);
2107
2136
  };
2108
2137
  })(window, document, 'ttq');
2109
2138
  // Initialize pixel
@@ -2119,7 +2148,7 @@ class ContainerManager {
2119
2148
  * Track event to all initialized pixels
2120
2149
  */
2121
2150
  trackToPixels(eventName, properties = {}) {
2122
- var _a, _b, _c, _d, _e, _f;
2151
+ var _a, _b, _c, _e, _f, _g;
2123
2152
  // Track to Meta Pixel
2124
2153
  if (((_b = (_a = this.pixels) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.enabled) && window.fbq) {
2125
2154
  try {
@@ -2130,7 +2159,7 @@ class ContainerManager {
2130
2159
  }
2131
2160
  }
2132
2161
  // Track to Google Tag
2133
- if (((_d = (_c = this.pixels) === null || _c === void 0 ? void 0 : _c.google) === null || _d === void 0 ? void 0 : _d.enabled) && window.gtag) {
2162
+ if (((_e = (_c = this.pixels) === null || _c === void 0 ? void 0 : _c.google) === null || _e === void 0 ? void 0 : _e.enabled) && window.gtag) {
2134
2163
  try {
2135
2164
  window.gtag('event', eventName, properties);
2136
2165
  }
@@ -2139,7 +2168,7 @@ class ContainerManager {
2139
2168
  }
2140
2169
  }
2141
2170
  // Track to TikTok Pixel
2142
- if (((_f = (_e = this.pixels) === null || _e === void 0 ? void 0 : _e.tiktok) === null || _f === void 0 ? void 0 : _f.enabled) && window.ttq) {
2171
+ if (((_g = (_f = this.pixels) === null || _f === void 0 ? void 0 : _f.tiktok) === null || _g === void 0 ? void 0 : _g.enabled) && window.ttq) {
2143
2172
  try {
2144
2173
  // Map common events to TikTok names
2145
2174
  const tiktokEventMap = {
@@ -2641,13 +2670,39 @@ class Datalyr {
2641
2670
  // Create payload with both camelCase and snake_case fields
2642
2671
  const identityFields = this.identity.getIdentityFields();
2643
2672
  const eventId = generateUUID();
2644
- const payload = Object.assign(Object.assign({
2673
+ // Ensure we have all required identity fields
2674
+ const distinctId = identityFields.distinct_id;
2675
+ const anonymousId = identityFields.anonymous_id;
2676
+ const visitorId = identityFields.visitor_id || anonymousId;
2677
+ const sessionId = identityFields.session_id;
2678
+ const payload = {
2645
2679
  // Required fields
2646
- workspaceId: this.config.workspaceId, workspace_id: this.config.workspaceId, eventId: eventId, event_id: eventId, // Snake case alias (same ID)
2647
- eventName, event_name: eventName, // Snake case alias
2648
- eventData, event_data: eventData, source: 'web', timestamp: new Date().toISOString() }, identityFields), {
2680
+ workspaceId: this.config.workspaceId,
2681
+ workspace_id: this.config.workspaceId, // Snake case alias
2682
+ eventId: eventId,
2683
+ event_id: eventId, // Snake case alias (same ID)
2684
+ eventName,
2685
+ event_name: eventName, // Snake case alias
2686
+ eventData,
2687
+ event_data: eventData, // Snake case alias
2688
+ source: 'web',
2689
+ timestamp: new Date().toISOString(),
2690
+ // Identity fields (explicit to satisfy TypeScript)
2691
+ distinct_id: distinctId,
2692
+ anonymous_id: anonymousId,
2693
+ visitor_id: visitorId,
2694
+ visitorId: visitorId,
2695
+ user_id: identityFields.user_id,
2696
+ canonical_id: identityFields.canonical_id,
2697
+ sessionId: sessionId,
2698
+ session_id: sessionId,
2699
+ // Resolution metadata
2700
+ resolution_method: 'browser_sdk',
2701
+ resolution_confidence: 1.0,
2649
2702
  // SDK metadata
2650
- sdk_version: '1.0.0', sdk_name: 'datalyr-web-sdk' });
2703
+ sdk_version: '1.0.0',
2704
+ sdk_name: 'datalyr-web-sdk'
2705
+ };
2651
2706
  return payload;
2652
2707
  }
2653
2708
  /**