@blinkdotnew/sdk 0.8.0 → 0.9.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
@@ -580,9 +580,12 @@ blink.analytics.log('button_clicked', {
580
580
  })
581
581
 
582
582
  // All events automatically include:
583
- // - timestamp, project_id, user_id, session_id
583
+ // - timestamp, project_id, user_id, user_email, session_id
584
584
  // - pathname (current page), referrer, screen_width
585
585
  // - device/browser/OS info (parsed server-side)
586
+ // - channel detection (Organic Search, Social, Direct, etc.)
587
+ // - UTM parameters (source, medium, campaign, content, term)
588
+ // - entry_page, exit_page tracking
586
589
 
587
590
  // Control analytics
588
591
  blink.analytics.disable()
package/dist/index.d.mts CHANGED
@@ -257,10 +257,19 @@ interface AnalyticsEvent {
257
257
  type: string;
258
258
  timestamp?: string;
259
259
  user_id?: string | null;
260
+ user_email?: string | null;
260
261
  session_id?: string | null;
261
262
  pathname?: string | null;
262
263
  referrer?: string | null;
263
264
  screen_width?: number | null;
265
+ channel?: string | null;
266
+ utm_source?: string | null;
267
+ utm_medium?: string | null;
268
+ utm_campaign?: string | null;
269
+ utm_content?: string | null;
270
+ utm_term?: string | null;
271
+ entry_page?: string | null;
272
+ exit_page?: string | null;
264
273
  [key: string]: any;
265
274
  }
266
275
  interface BlinkAnalytics {
@@ -269,6 +278,7 @@ interface BlinkAnalytics {
269
278
  enable(): void;
270
279
  isEnabled(): boolean;
271
280
  setUserId(userId: string | null): void;
281
+ setUserEmail(email: string | null): void;
272
282
  }
273
283
  declare class BlinkAnalyticsImpl implements BlinkAnalytics {
274
284
  private httpClient;
@@ -277,7 +287,10 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
277
287
  private timer;
278
288
  private enabled;
279
289
  private userId;
290
+ private userEmail;
280
291
  private hasTrackedPageview;
292
+ private entryPage;
293
+ private utmParams;
281
294
  constructor(httpClient: HttpClient, projectId: string);
282
295
  /**
283
296
  * Log a custom analytics event
@@ -299,6 +312,10 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
299
312
  * Set the user ID for analytics events
300
313
  */
301
314
  setUserId(userId: string | null): void;
315
+ /**
316
+ * Set the user email for analytics events
317
+ */
318
+ setUserEmail(email: string | null): void;
302
319
  private buildEvent;
303
320
  private sanitizeData;
304
321
  private enqueue;
@@ -311,6 +328,8 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
311
328
  private trackPageview;
312
329
  private setupRouteChangeListener;
313
330
  private setupUnloadListener;
331
+ private captureUTMParams;
332
+ private detectChannel;
314
333
  }
315
334
 
316
335
  /**
package/dist/index.d.ts CHANGED
@@ -257,10 +257,19 @@ interface AnalyticsEvent {
257
257
  type: string;
258
258
  timestamp?: string;
259
259
  user_id?: string | null;
260
+ user_email?: string | null;
260
261
  session_id?: string | null;
261
262
  pathname?: string | null;
262
263
  referrer?: string | null;
263
264
  screen_width?: number | null;
265
+ channel?: string | null;
266
+ utm_source?: string | null;
267
+ utm_medium?: string | null;
268
+ utm_campaign?: string | null;
269
+ utm_content?: string | null;
270
+ utm_term?: string | null;
271
+ entry_page?: string | null;
272
+ exit_page?: string | null;
264
273
  [key: string]: any;
265
274
  }
266
275
  interface BlinkAnalytics {
@@ -269,6 +278,7 @@ interface BlinkAnalytics {
269
278
  enable(): void;
270
279
  isEnabled(): boolean;
271
280
  setUserId(userId: string | null): void;
281
+ setUserEmail(email: string | null): void;
272
282
  }
273
283
  declare class BlinkAnalyticsImpl implements BlinkAnalytics {
274
284
  private httpClient;
@@ -277,7 +287,10 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
277
287
  private timer;
278
288
  private enabled;
279
289
  private userId;
290
+ private userEmail;
280
291
  private hasTrackedPageview;
292
+ private entryPage;
293
+ private utmParams;
281
294
  constructor(httpClient: HttpClient, projectId: string);
282
295
  /**
283
296
  * Log a custom analytics event
@@ -299,6 +312,10 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
299
312
  * Set the user ID for analytics events
300
313
  */
301
314
  setUserId(userId: string | null): void;
315
+ /**
316
+ * Set the user email for analytics events
317
+ */
318
+ setUserEmail(email: string | null): void;
302
319
  private buildEvent;
303
320
  private sanitizeData;
304
321
  private enqueue;
@@ -311,6 +328,8 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
311
328
  private trackPageview;
312
329
  private setupRouteChangeListener;
313
330
  private setupUnloadListener;
331
+ private captureUTMParams;
332
+ private detectChannel;
314
333
  }
315
334
 
316
335
  /**
package/dist/index.js CHANGED
@@ -2894,7 +2894,10 @@ var BlinkAnalyticsImpl = class {
2894
2894
  timer = null;
2895
2895
  enabled = true;
2896
2896
  userId = null;
2897
+ userEmail = null;
2897
2898
  hasTrackedPageview = false;
2899
+ entryPage = null;
2900
+ utmParams = {};
2898
2901
  constructor(httpClient, projectId) {
2899
2902
  this.httpClient = httpClient;
2900
2903
  this.projectId = projectId;
@@ -2905,6 +2908,8 @@ var BlinkAnalyticsImpl = class {
2905
2908
  this.enabled = false;
2906
2909
  return;
2907
2910
  }
2911
+ this.entryPage = window.location.pathname;
2912
+ this.captureUTMParams();
2908
2913
  this.loadQueue();
2909
2914
  this.trackPageview();
2910
2915
  this.setupRouteChangeListener();
@@ -2945,18 +2950,35 @@ var BlinkAnalyticsImpl = class {
2945
2950
  setUserId(userId) {
2946
2951
  this.userId = userId;
2947
2952
  }
2953
+ /**
2954
+ * Set the user email for analytics events
2955
+ */
2956
+ setUserEmail(email) {
2957
+ this.userEmail = email;
2958
+ }
2948
2959
  // Private methods
2949
2960
  buildEvent(type, data = {}) {
2950
2961
  const sessionId = this.getOrCreateSessionId();
2962
+ const channel = this.detectChannel();
2951
2963
  return {
2952
2964
  type,
2953
2965
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2954
2966
  project_id: this.projectId,
2955
2967
  user_id: this.userId,
2968
+ user_email: this.userEmail,
2956
2969
  session_id: sessionId,
2957
2970
  pathname: window.location.pathname,
2958
2971
  referrer: document.referrer || null,
2959
2972
  screen_width: window.innerWidth,
2973
+ 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
2960
2982
  ...this.sanitizeData(data)
2961
2983
  };
2962
2984
  }
@@ -3091,6 +3113,46 @@ var BlinkAnalyticsImpl = class {
3091
3113
  this.flush();
3092
3114
  });
3093
3115
  }
3116
+ captureUTMParams() {
3117
+ const urlParams = new URLSearchParams(window.location.search);
3118
+ this.utmParams = {
3119
+ utm_source: urlParams.get("utm_source"),
3120
+ utm_medium: urlParams.get("utm_medium"),
3121
+ utm_campaign: urlParams.get("utm_campaign"),
3122
+ utm_content: urlParams.get("utm_content"),
3123
+ utm_term: urlParams.get("utm_term")
3124
+ };
3125
+ }
3126
+ detectChannel() {
3127
+ const referrer = document.referrer;
3128
+ const utmMedium = this.utmParams.utm_medium;
3129
+ this.utmParams.utm_source;
3130
+ if (utmMedium) {
3131
+ if (utmMedium === "cpc" || utmMedium === "ppc") return "Paid Search";
3132
+ if (utmMedium === "email") return "Email";
3133
+ if (utmMedium === "social") return "Social";
3134
+ if (utmMedium === "referral") return "Referral";
3135
+ if (utmMedium === "display") return "Display";
3136
+ if (utmMedium === "affiliate") return "Affiliate";
3137
+ }
3138
+ if (!referrer) return "Direct";
3139
+ try {
3140
+ const referrerUrl = new URL(referrer);
3141
+ const referrerDomain = referrerUrl.hostname.toLowerCase();
3142
+ if (/google\.|bing\.|yahoo\.|duckduckgo\.|baidu\.|yandex\./.test(referrerDomain)) {
3143
+ return "Organic Search";
3144
+ }
3145
+ if (/facebook\.|twitter\.|linkedin\.|instagram\.|youtube\.|tiktok\.|reddit\./.test(referrerDomain)) {
3146
+ return "Social";
3147
+ }
3148
+ if (/mail\.|outlook\.|gmail\./.test(referrerDomain)) {
3149
+ return "Email";
3150
+ }
3151
+ return "Referral";
3152
+ } catch {
3153
+ return "Direct";
3154
+ }
3155
+ }
3094
3156
  };
3095
3157
 
3096
3158
  // src/client.ts
@@ -3121,8 +3183,10 @@ var BlinkClientImpl = class {
3121
3183
  this.auth.onAuthStateChanged((state) => {
3122
3184
  if (state.isAuthenticated && state.user) {
3123
3185
  this.analytics.setUserId(state.user.id);
3186
+ this.analytics.setUserEmail(state.user.email);
3124
3187
  } else {
3125
3188
  this.analytics.setUserId(null);
3189
+ this.analytics.setUserEmail(null);
3126
3190
  }
3127
3191
  });
3128
3192
  }
package/dist/index.mjs CHANGED
@@ -2892,7 +2892,10 @@ var BlinkAnalyticsImpl = class {
2892
2892
  timer = null;
2893
2893
  enabled = true;
2894
2894
  userId = null;
2895
+ userEmail = null;
2895
2896
  hasTrackedPageview = false;
2897
+ entryPage = null;
2898
+ utmParams = {};
2896
2899
  constructor(httpClient, projectId) {
2897
2900
  this.httpClient = httpClient;
2898
2901
  this.projectId = projectId;
@@ -2903,6 +2906,8 @@ var BlinkAnalyticsImpl = class {
2903
2906
  this.enabled = false;
2904
2907
  return;
2905
2908
  }
2909
+ this.entryPage = window.location.pathname;
2910
+ this.captureUTMParams();
2906
2911
  this.loadQueue();
2907
2912
  this.trackPageview();
2908
2913
  this.setupRouteChangeListener();
@@ -2943,18 +2948,35 @@ var BlinkAnalyticsImpl = class {
2943
2948
  setUserId(userId) {
2944
2949
  this.userId = userId;
2945
2950
  }
2951
+ /**
2952
+ * Set the user email for analytics events
2953
+ */
2954
+ setUserEmail(email) {
2955
+ this.userEmail = email;
2956
+ }
2946
2957
  // Private methods
2947
2958
  buildEvent(type, data = {}) {
2948
2959
  const sessionId = this.getOrCreateSessionId();
2960
+ const channel = this.detectChannel();
2949
2961
  return {
2950
2962
  type,
2951
2963
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2952
2964
  project_id: this.projectId,
2953
2965
  user_id: this.userId,
2966
+ user_email: this.userEmail,
2954
2967
  session_id: sessionId,
2955
2968
  pathname: window.location.pathname,
2956
2969
  referrer: document.referrer || null,
2957
2970
  screen_width: window.innerWidth,
2971
+ 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
2958
2980
  ...this.sanitizeData(data)
2959
2981
  };
2960
2982
  }
@@ -3089,6 +3111,46 @@ var BlinkAnalyticsImpl = class {
3089
3111
  this.flush();
3090
3112
  });
3091
3113
  }
3114
+ captureUTMParams() {
3115
+ const urlParams = new URLSearchParams(window.location.search);
3116
+ this.utmParams = {
3117
+ utm_source: urlParams.get("utm_source"),
3118
+ utm_medium: urlParams.get("utm_medium"),
3119
+ utm_campaign: urlParams.get("utm_campaign"),
3120
+ utm_content: urlParams.get("utm_content"),
3121
+ utm_term: urlParams.get("utm_term")
3122
+ };
3123
+ }
3124
+ detectChannel() {
3125
+ const referrer = document.referrer;
3126
+ const utmMedium = this.utmParams.utm_medium;
3127
+ this.utmParams.utm_source;
3128
+ if (utmMedium) {
3129
+ if (utmMedium === "cpc" || utmMedium === "ppc") return "Paid Search";
3130
+ if (utmMedium === "email") return "Email";
3131
+ if (utmMedium === "social") return "Social";
3132
+ if (utmMedium === "referral") return "Referral";
3133
+ if (utmMedium === "display") return "Display";
3134
+ if (utmMedium === "affiliate") return "Affiliate";
3135
+ }
3136
+ if (!referrer) return "Direct";
3137
+ try {
3138
+ const referrerUrl = new URL(referrer);
3139
+ const referrerDomain = referrerUrl.hostname.toLowerCase();
3140
+ if (/google\.|bing\.|yahoo\.|duckduckgo\.|baidu\.|yandex\./.test(referrerDomain)) {
3141
+ return "Organic Search";
3142
+ }
3143
+ if (/facebook\.|twitter\.|linkedin\.|instagram\.|youtube\.|tiktok\.|reddit\./.test(referrerDomain)) {
3144
+ return "Social";
3145
+ }
3146
+ if (/mail\.|outlook\.|gmail\./.test(referrerDomain)) {
3147
+ return "Email";
3148
+ }
3149
+ return "Referral";
3150
+ } catch {
3151
+ return "Direct";
3152
+ }
3153
+ }
3092
3154
  };
3093
3155
 
3094
3156
  // src/client.ts
@@ -3119,8 +3181,10 @@ var BlinkClientImpl = class {
3119
3181
  this.auth.onAuthStateChanged((state) => {
3120
3182
  if (state.isAuthenticated && state.user) {
3121
3183
  this.analytics.setUserId(state.user.id);
3184
+ this.analytics.setUserEmail(state.user.email);
3122
3185
  } else {
3123
3186
  this.analytics.setUserId(null);
3187
+ this.analytics.setUserEmail(null);
3124
3188
  }
3125
3189
  });
3126
3190
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinkdotnew/sdk",
3
- "version": "0.8.0",
3
+ "version": "0.9.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",