@blinkdotnew/sdk 0.9.0 → 0.10.0

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/README.md CHANGED
@@ -585,14 +585,18 @@ blink.analytics.log('button_clicked', {
585
585
  // - device/browser/OS info (parsed server-side)
586
586
  // - channel detection (Organic Search, Social, Direct, etc.)
587
587
  // - UTM parameters (source, medium, campaign, content, term)
588
- // - entry_page, exit_page tracking
588
+ // - UTM persistence for attribution tracking across sessions
589
589
 
590
590
  // Control analytics
591
591
  blink.analytics.disable()
592
592
  blink.analytics.enable()
593
593
  const isEnabled = blink.analytics.isEnabled()
594
594
 
595
+ // Clear attribution data (e.g., when user logs out)
596
+ blink.analytics.clearAttribution()
597
+
595
598
  // Features: Privacy-first, offline support, event batching, session management
599
+ // Attribution: UTM params persist across sessions for conversion tracking
596
600
  ```
597
601
 
598
602
  ### Realtime Operations
package/dist/index.d.mts CHANGED
@@ -268,8 +268,6 @@ interface AnalyticsEvent {
268
268
  utm_campaign?: string | null;
269
269
  utm_content?: string | null;
270
270
  utm_term?: string | null;
271
- entry_page?: string | null;
272
- exit_page?: string | null;
273
271
  [key: string]: any;
274
272
  }
275
273
  interface BlinkAnalytics {
@@ -279,6 +277,7 @@ interface BlinkAnalytics {
279
277
  isEnabled(): boolean;
280
278
  setUserId(userId: string | null): void;
281
279
  setUserEmail(email: string | null): void;
280
+ clearAttribution(): void;
282
281
  }
283
282
  declare class BlinkAnalyticsImpl implements BlinkAnalytics {
284
283
  private httpClient;
@@ -289,8 +288,8 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
289
288
  private userId;
290
289
  private userEmail;
291
290
  private hasTrackedPageview;
292
- private entryPage;
293
291
  private utmParams;
292
+ private persistedAttribution;
294
293
  constructor(httpClient: HttpClient, projectId: string);
295
294
  /**
296
295
  * Log a custom analytics event
@@ -316,6 +315,10 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
316
315
  * Set the user email for analytics events
317
316
  */
318
317
  setUserEmail(email: string | null): void;
318
+ /**
319
+ * Clear persisted attribution data
320
+ */
321
+ clearAttribution(): void;
319
322
  private buildEvent;
320
323
  private sanitizeData;
321
324
  private enqueue;
@@ -329,6 +332,8 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
329
332
  private setupRouteChangeListener;
330
333
  private setupUnloadListener;
331
334
  private captureUTMParams;
335
+ private loadPersistedAttribution;
336
+ private persistAttribution;
332
337
  private detectChannel;
333
338
  }
334
339
 
package/dist/index.d.ts CHANGED
@@ -268,8 +268,6 @@ interface AnalyticsEvent {
268
268
  utm_campaign?: string | null;
269
269
  utm_content?: string | null;
270
270
  utm_term?: string | null;
271
- entry_page?: string | null;
272
- exit_page?: string | null;
273
271
  [key: string]: any;
274
272
  }
275
273
  interface BlinkAnalytics {
@@ -279,6 +277,7 @@ interface BlinkAnalytics {
279
277
  isEnabled(): boolean;
280
278
  setUserId(userId: string | null): void;
281
279
  setUserEmail(email: string | null): void;
280
+ clearAttribution(): void;
282
281
  }
283
282
  declare class BlinkAnalyticsImpl implements BlinkAnalytics {
284
283
  private httpClient;
@@ -289,8 +288,8 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
289
288
  private userId;
290
289
  private userEmail;
291
290
  private hasTrackedPageview;
292
- private entryPage;
293
291
  private utmParams;
292
+ private persistedAttribution;
294
293
  constructor(httpClient: HttpClient, projectId: string);
295
294
  /**
296
295
  * Log a custom analytics event
@@ -316,6 +315,10 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
316
315
  * Set the user email for analytics events
317
316
  */
318
317
  setUserEmail(email: string | null): void;
318
+ /**
319
+ * Clear persisted attribution data
320
+ */
321
+ clearAttribution(): void;
319
322
  private buildEvent;
320
323
  private sanitizeData;
321
324
  private enqueue;
@@ -329,6 +332,8 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
329
332
  private setupRouteChangeListener;
330
333
  private setupUnloadListener;
331
334
  private captureUTMParams;
335
+ private loadPersistedAttribution;
336
+ private persistAttribution;
332
337
  private detectChannel;
333
338
  }
334
339
 
package/dist/index.js CHANGED
@@ -2887,6 +2887,7 @@ var BATCH_TIMEOUT = 3e3;
2887
2887
  var MAX_STRING_LENGTH = 256;
2888
2888
  var STORAGE_KEY_QUEUE = "blinkAnalyticsQueue";
2889
2889
  var STORAGE_KEY_SESSION = "blinkAnalyticsSession";
2890
+ var STORAGE_KEY_ATTRIBUTION = "blinkAnalyticsAttribution";
2890
2891
  var BlinkAnalyticsImpl = class {
2891
2892
  httpClient;
2892
2893
  projectId;
@@ -2896,8 +2897,8 @@ var BlinkAnalyticsImpl = class {
2896
2897
  userId = null;
2897
2898
  userEmail = null;
2898
2899
  hasTrackedPageview = false;
2899
- entryPage = null;
2900
2900
  utmParams = {};
2901
+ persistedAttribution = {};
2901
2902
  constructor(httpClient, projectId) {
2902
2903
  this.httpClient = httpClient;
2903
2904
  this.projectId = projectId;
@@ -2908,7 +2909,7 @@ var BlinkAnalyticsImpl = class {
2908
2909
  this.enabled = false;
2909
2910
  return;
2910
2911
  }
2911
- this.entryPage = window.location.pathname;
2912
+ this.loadPersistedAttribution();
2912
2913
  this.captureUTMParams();
2913
2914
  this.loadQueue();
2914
2915
  this.trackPageview();
@@ -2956,6 +2957,16 @@ var BlinkAnalyticsImpl = class {
2956
2957
  setUserEmail(email) {
2957
2958
  this.userEmail = email;
2958
2959
  }
2960
+ /**
2961
+ * Clear persisted attribution data
2962
+ */
2963
+ clearAttribution() {
2964
+ this.persistedAttribution = {};
2965
+ try {
2966
+ localStorage.removeItem(STORAGE_KEY_ATTRIBUTION);
2967
+ } catch {
2968
+ }
2969
+ }
2959
2970
  // Private methods
2960
2971
  buildEvent(type, data = {}) {
2961
2972
  const sessionId = this.getOrCreateSessionId();
@@ -2971,14 +2982,11 @@ var BlinkAnalyticsImpl = class {
2971
2982
  referrer: document.referrer || null,
2972
2983
  screen_width: window.innerWidth,
2973
2984
  channel,
2974
- utm_source: this.utmParams.utm_source || null,
2975
- utm_medium: this.utmParams.utm_medium || null,
2976
- utm_campaign: this.utmParams.utm_campaign || null,
2977
- utm_content: this.utmParams.utm_content || null,
2978
- utm_term: this.utmParams.utm_term || null,
2979
- entry_page: this.entryPage,
2980
- exit_page: window.location.pathname,
2981
- // Current page is potential exit
2985
+ utm_source: this.utmParams.utm_source || this.persistedAttribution.utm_source || null,
2986
+ utm_medium: this.utmParams.utm_medium || this.persistedAttribution.utm_medium || null,
2987
+ utm_campaign: this.utmParams.utm_campaign || this.persistedAttribution.utm_campaign || null,
2988
+ utm_content: this.utmParams.utm_content || this.persistedAttribution.utm_content || null,
2989
+ utm_term: this.utmParams.utm_term || this.persistedAttribution.utm_term || null,
2982
2990
  ...this.sanitizeData(data)
2983
2991
  };
2984
2992
  }
@@ -3122,6 +3130,33 @@ var BlinkAnalyticsImpl = class {
3122
3130
  utm_content: urlParams.get("utm_content"),
3123
3131
  utm_term: urlParams.get("utm_term")
3124
3132
  };
3133
+ const hasNewParams = Object.values(this.utmParams).some((v) => v !== null);
3134
+ if (hasNewParams) {
3135
+ this.persistAttribution();
3136
+ }
3137
+ }
3138
+ loadPersistedAttribution() {
3139
+ try {
3140
+ const stored = localStorage.getItem(STORAGE_KEY_ATTRIBUTION);
3141
+ if (stored) {
3142
+ this.persistedAttribution = JSON.parse(stored);
3143
+ }
3144
+ } catch {
3145
+ this.persistedAttribution = {};
3146
+ }
3147
+ }
3148
+ persistAttribution() {
3149
+ try {
3150
+ const attribution = {
3151
+ ...this.persistedAttribution,
3152
+ ...Object.fromEntries(
3153
+ Object.entries(this.utmParams).filter(([_, v]) => v !== null)
3154
+ )
3155
+ };
3156
+ localStorage.setItem(STORAGE_KEY_ATTRIBUTION, JSON.stringify(attribution));
3157
+ this.persistedAttribution = attribution;
3158
+ } catch {
3159
+ }
3125
3160
  }
3126
3161
  detectChannel() {
3127
3162
  const referrer = document.referrer;
package/dist/index.mjs CHANGED
@@ -2885,6 +2885,7 @@ var BATCH_TIMEOUT = 3e3;
2885
2885
  var MAX_STRING_LENGTH = 256;
2886
2886
  var STORAGE_KEY_QUEUE = "blinkAnalyticsQueue";
2887
2887
  var STORAGE_KEY_SESSION = "blinkAnalyticsSession";
2888
+ var STORAGE_KEY_ATTRIBUTION = "blinkAnalyticsAttribution";
2888
2889
  var BlinkAnalyticsImpl = class {
2889
2890
  httpClient;
2890
2891
  projectId;
@@ -2894,8 +2895,8 @@ var BlinkAnalyticsImpl = class {
2894
2895
  userId = null;
2895
2896
  userEmail = null;
2896
2897
  hasTrackedPageview = false;
2897
- entryPage = null;
2898
2898
  utmParams = {};
2899
+ persistedAttribution = {};
2899
2900
  constructor(httpClient, projectId) {
2900
2901
  this.httpClient = httpClient;
2901
2902
  this.projectId = projectId;
@@ -2906,7 +2907,7 @@ var BlinkAnalyticsImpl = class {
2906
2907
  this.enabled = false;
2907
2908
  return;
2908
2909
  }
2909
- this.entryPage = window.location.pathname;
2910
+ this.loadPersistedAttribution();
2910
2911
  this.captureUTMParams();
2911
2912
  this.loadQueue();
2912
2913
  this.trackPageview();
@@ -2954,6 +2955,16 @@ var BlinkAnalyticsImpl = class {
2954
2955
  setUserEmail(email) {
2955
2956
  this.userEmail = email;
2956
2957
  }
2958
+ /**
2959
+ * Clear persisted attribution data
2960
+ */
2961
+ clearAttribution() {
2962
+ this.persistedAttribution = {};
2963
+ try {
2964
+ localStorage.removeItem(STORAGE_KEY_ATTRIBUTION);
2965
+ } catch {
2966
+ }
2967
+ }
2957
2968
  // Private methods
2958
2969
  buildEvent(type, data = {}) {
2959
2970
  const sessionId = this.getOrCreateSessionId();
@@ -2969,14 +2980,11 @@ var BlinkAnalyticsImpl = class {
2969
2980
  referrer: document.referrer || null,
2970
2981
  screen_width: window.innerWidth,
2971
2982
  channel,
2972
- utm_source: this.utmParams.utm_source || null,
2973
- utm_medium: this.utmParams.utm_medium || null,
2974
- utm_campaign: this.utmParams.utm_campaign || null,
2975
- utm_content: this.utmParams.utm_content || null,
2976
- utm_term: this.utmParams.utm_term || null,
2977
- entry_page: this.entryPage,
2978
- exit_page: window.location.pathname,
2979
- // Current page is potential exit
2983
+ utm_source: this.utmParams.utm_source || this.persistedAttribution.utm_source || null,
2984
+ utm_medium: this.utmParams.utm_medium || this.persistedAttribution.utm_medium || null,
2985
+ utm_campaign: this.utmParams.utm_campaign || this.persistedAttribution.utm_campaign || null,
2986
+ utm_content: this.utmParams.utm_content || this.persistedAttribution.utm_content || null,
2987
+ utm_term: this.utmParams.utm_term || this.persistedAttribution.utm_term || null,
2980
2988
  ...this.sanitizeData(data)
2981
2989
  };
2982
2990
  }
@@ -3120,6 +3128,33 @@ var BlinkAnalyticsImpl = class {
3120
3128
  utm_content: urlParams.get("utm_content"),
3121
3129
  utm_term: urlParams.get("utm_term")
3122
3130
  };
3131
+ const hasNewParams = Object.values(this.utmParams).some((v) => v !== null);
3132
+ if (hasNewParams) {
3133
+ this.persistAttribution();
3134
+ }
3135
+ }
3136
+ loadPersistedAttribution() {
3137
+ try {
3138
+ const stored = localStorage.getItem(STORAGE_KEY_ATTRIBUTION);
3139
+ if (stored) {
3140
+ this.persistedAttribution = JSON.parse(stored);
3141
+ }
3142
+ } catch {
3143
+ this.persistedAttribution = {};
3144
+ }
3145
+ }
3146
+ persistAttribution() {
3147
+ try {
3148
+ const attribution = {
3149
+ ...this.persistedAttribution,
3150
+ ...Object.fromEntries(
3151
+ Object.entries(this.utmParams).filter(([_, v]) => v !== null)
3152
+ )
3153
+ };
3154
+ localStorage.setItem(STORAGE_KEY_ATTRIBUTION, JSON.stringify(attribution));
3155
+ this.persistedAttribution = attribution;
3156
+ } catch {
3157
+ }
3123
3158
  }
3124
3159
  detectChannel() {
3125
3160
  const referrer = document.referrer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinkdotnew/sdk",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Blink TypeScript SDK for client-side applications - Zero-boilerplate CRUD + auth + AI + analytics + notifications for modern SaaS/AI apps",
5
5
  "keywords": [
6
6
  "blink",