@grainql/analytics-web 1.2.0 → 1.3.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/dist/index.js CHANGED
@@ -11,6 +11,7 @@ class GrainAnalytics {
11
11
  this.eventQueue = [];
12
12
  this.flushTimer = null;
13
13
  this.isDestroyed = false;
14
+ this.globalUserId = null;
14
15
  this.config = {
15
16
  apiUrl: 'https://api.grainql.com',
16
17
  authStrategy: 'NONE',
@@ -23,6 +24,10 @@ class GrainAnalytics {
23
24
  ...config,
24
25
  tenantId: config.tenantId,
25
26
  };
27
+ // Set global userId if provided in config
28
+ if (config.userId) {
29
+ this.globalUserId = config.userId;
30
+ }
26
31
  this.validateConfig();
27
32
  this.setupBeforeUnload();
28
33
  this.startFlushTimer();
@@ -46,7 +51,7 @@ class GrainAnalytics {
46
51
  formatEvent(event) {
47
52
  return {
48
53
  eventName: event.eventName,
49
- userId: event.userId || 'anonymous',
54
+ userId: event.userId || this.globalUserId || 'anonymous',
50
55
  properties: event.properties || {},
51
56
  };
52
57
  }
@@ -104,7 +109,7 @@ class GrainAnalytics {
104
109
  const response = await fetch(url, {
105
110
  method: 'POST',
106
111
  headers,
107
- body: JSON.stringify(events),
112
+ body: JSON.stringify({ events }),
108
113
  });
109
114
  if (!response.ok) {
110
115
  let errorMessage = `HTTP ${response.status}`;
@@ -250,9 +255,70 @@ class GrainAnalytics {
250
255
  * Identify a user (sets userId for subsequent events)
251
256
  */
252
257
  identify(userId) {
253
- // Store userId for future events - this would typically be handled
254
- // by the application layer, but we can provide a helper
255
258
  this.log(`Identified user: ${userId}`);
259
+ this.globalUserId = userId;
260
+ }
261
+ /**
262
+ * Set global user ID for all subsequent events
263
+ */
264
+ setUserId(userId) {
265
+ this.log(`Set global user ID: ${userId}`);
266
+ this.globalUserId = userId;
267
+ }
268
+ /**
269
+ * Get current global user ID
270
+ */
271
+ getUserId() {
272
+ return this.globalUserId;
273
+ }
274
+ // Template event methods
275
+ /**
276
+ * Track user login event
277
+ */
278
+ async trackLogin(properties, options) {
279
+ return this.track('login', properties, options);
280
+ }
281
+ /**
282
+ * Track user signup event
283
+ */
284
+ async trackSignup(properties, options) {
285
+ return this.track('signup', properties, options);
286
+ }
287
+ /**
288
+ * Track checkout event
289
+ */
290
+ async trackCheckout(properties, options) {
291
+ return this.track('checkout', properties, options);
292
+ }
293
+ /**
294
+ * Track page view event
295
+ */
296
+ async trackPageView(properties, options) {
297
+ return this.track('page_view', properties, options);
298
+ }
299
+ /**
300
+ * Track purchase event
301
+ */
302
+ async trackPurchase(properties, options) {
303
+ return this.track('purchase', properties, options);
304
+ }
305
+ /**
306
+ * Track search event
307
+ */
308
+ async trackSearch(properties, options) {
309
+ return this.track('search', properties, options);
310
+ }
311
+ /**
312
+ * Track add to cart event
313
+ */
314
+ async trackAddToCart(properties, options) {
315
+ return this.track('add_to_cart', properties, options);
316
+ }
317
+ /**
318
+ * Track remove from cart event
319
+ */
320
+ async trackRemoveFromCart(properties, options) {
321
+ return this.track('remove_from_cart', properties, options);
256
322
  }
257
323
  /**
258
324
  * Manually flush all queued events
package/dist/index.mjs CHANGED
@@ -7,6 +7,7 @@ export class GrainAnalytics {
7
7
  this.eventQueue = [];
8
8
  this.flushTimer = null;
9
9
  this.isDestroyed = false;
10
+ this.globalUserId = null;
10
11
  this.config = {
11
12
  apiUrl: 'https://api.grainql.com',
12
13
  authStrategy: 'NONE',
@@ -19,6 +20,10 @@ export class GrainAnalytics {
19
20
  ...config,
20
21
  tenantId: config.tenantId,
21
22
  };
23
+ // Set global userId if provided in config
24
+ if (config.userId) {
25
+ this.globalUserId = config.userId;
26
+ }
22
27
  this.validateConfig();
23
28
  this.setupBeforeUnload();
24
29
  this.startFlushTimer();
@@ -42,7 +47,7 @@ export class GrainAnalytics {
42
47
  formatEvent(event) {
43
48
  return {
44
49
  eventName: event.eventName,
45
- userId: event.userId || 'anonymous',
50
+ userId: event.userId || this.globalUserId || 'anonymous',
46
51
  properties: event.properties || {},
47
52
  };
48
53
  }
@@ -100,7 +105,7 @@ export class GrainAnalytics {
100
105
  const response = await fetch(url, {
101
106
  method: 'POST',
102
107
  headers,
103
- body: JSON.stringify(events),
108
+ body: JSON.stringify({ events }),
104
109
  });
105
110
  if (!response.ok) {
106
111
  let errorMessage = `HTTP ${response.status}`;
@@ -246,9 +251,70 @@ export class GrainAnalytics {
246
251
  * Identify a user (sets userId for subsequent events)
247
252
  */
248
253
  identify(userId) {
249
- // Store userId for future events - this would typically be handled
250
- // by the application layer, but we can provide a helper
251
254
  this.log(`Identified user: ${userId}`);
255
+ this.globalUserId = userId;
256
+ }
257
+ /**
258
+ * Set global user ID for all subsequent events
259
+ */
260
+ setUserId(userId) {
261
+ this.log(`Set global user ID: ${userId}`);
262
+ this.globalUserId = userId;
263
+ }
264
+ /**
265
+ * Get current global user ID
266
+ */
267
+ getUserId() {
268
+ return this.globalUserId;
269
+ }
270
+ // Template event methods
271
+ /**
272
+ * Track user login event
273
+ */
274
+ async trackLogin(properties, options) {
275
+ return this.track('login', properties, options);
276
+ }
277
+ /**
278
+ * Track user signup event
279
+ */
280
+ async trackSignup(properties, options) {
281
+ return this.track('signup', properties, options);
282
+ }
283
+ /**
284
+ * Track checkout event
285
+ */
286
+ async trackCheckout(properties, options) {
287
+ return this.track('checkout', properties, options);
288
+ }
289
+ /**
290
+ * Track page view event
291
+ */
292
+ async trackPageView(properties, options) {
293
+ return this.track('page_view', properties, options);
294
+ }
295
+ /**
296
+ * Track purchase event
297
+ */
298
+ async trackPurchase(properties, options) {
299
+ return this.track('purchase', properties, options);
300
+ }
301
+ /**
302
+ * Track search event
303
+ */
304
+ async trackSearch(properties, options) {
305
+ return this.track('search', properties, options);
306
+ }
307
+ /**
308
+ * Track add to cart event
309
+ */
310
+ async trackAddToCart(properties, options) {
311
+ return this.track('add_to_cart', properties, options);
312
+ }
313
+ /**
314
+ * Track remove from cart event
315
+ */
316
+ async trackRemoveFromCart(properties, options) {
317
+ return this.track('remove_from_cart', properties, options);
252
318
  }
253
319
  /**
254
320
  * Manually flush all queued events
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grainql/analytics-web",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Lightweight TypeScript SDK for sending analytics events to Grain's REST API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -22,10 +22,10 @@
22
22
  "build:cjs": "tsc --module commonjs --target es2020 --outDir dist/cjs && mv dist/cjs/index.js dist/index.js",
23
23
  "build:iife": "node scripts/build-iife.js",
24
24
  "clean": "rm -rf dist",
25
- "test": "echo 'Tests disabled'",
26
- "test:watch": "echo 'Tests disabled'",
27
- "test:coverage": "echo 'Tests disabled'",
28
- "test:ci": "echo 'Tests disabled'",
25
+ "test": "jest",
26
+ "test:watch": "jest --watch",
27
+ "test:coverage": "jest --coverage",
28
+ "test:ci": "jest --ci --coverage",
29
29
  "prepublishOnly": "npm run clean && npm run build",
30
30
  "size": "npm run build && node scripts/bundle-analysis.js",
31
31
  "size:limit": "size-limit"