@bytem/bytem-tracker-app 0.0.17 → 0.0.19

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
@@ -7,7 +7,10 @@ This is the official Bytem Tracker SDK for React Native applications.
7
7
  Install the package using Yarn:
8
8
 
9
9
  ```bash
10
- yarn add @bytem/bytem-tracker-app @react-native-async-storage/async-storage
10
+ # need
11
+ yarn add @bytem/bytem-tracker-app
12
+ # if not
13
+ yarn add @react-native-async-storage/async-storage
11
14
  ```
12
15
 
13
16
  ### iOS Setup
@@ -31,7 +34,7 @@ const App = () => {
31
34
  await BytemTracker.init({
32
35
  appKey: 'your-app-key',
33
36
  endpoint: 'https://api.bytem.com/track',
34
- debug: __DEV__, // Enable debug logs in development
37
+ debug: false, // Enable debug logs in development
35
38
  });
36
39
  };
37
40
 
@@ -69,6 +72,9 @@ await BytemTracker.trackViewProduct({
69
72
  currency: 'USD',
70
73
  category: 'Electronics',
71
74
  url: 'https://example.com/products/prod-001'
75
+ }, {
76
+ source: 'Home Page',
77
+ position: 'Recommended'
72
78
  });
73
79
  ```
74
80
 
@@ -84,6 +90,9 @@ await BytemTracker.trackAddToCart({
84
90
  category: 'Electronics',
85
91
  url: 'https://example.com/products/prod-001',
86
92
  quantity: 1
93
+ }, {
94
+ source: 'Product Detail',
95
+ position: 'Bottom Bar'
87
96
  });
88
97
  ```
89
98
 
@@ -98,6 +107,9 @@ await BytemTracker.trackAddWishlist({
98
107
  currency: 'USD',
99
108
  category: 'Electronics',
100
109
  url: 'https://example.com/products/prod-001'
110
+ }, {
111
+ source: 'Product Detail',
112
+ position: 'Top Right'
101
113
  });
102
114
  ```
103
115
 
@@ -112,8 +124,10 @@ const products = [
112
124
 
113
125
  await BytemTracker.trackGoodsImpression(
114
126
  products,
115
- 'Home Page', // Source
116
- 'Recommended For You' // Position (optional)
127
+ {
128
+ source: 'Home Page',
129
+ position: 'Recommended For You'
130
+ }
117
131
  );
118
132
  ```
119
133
 
@@ -123,7 +137,7 @@ Track when a user clicks on a product.
123
137
  ```typescript
124
138
  await BytemTracker.trackGoodsClick({
125
139
  gid: 'prod_001', // Product ID
126
- url: 'https://example.com/p/1',
140
+ // url: 'https://example.com/p/1', // Optional
127
141
  source: 'Home Page',
128
142
  position: '1'
129
143
  });
@@ -141,6 +155,9 @@ await BytemTracker.trackCheckOutOrder({
141
155
  { productId: 'prod_001', price: 99.99, quantity: 1 },
142
156
  { productId: 'prod_002', price: 50.01, quantity: 1 }
143
157
  ]
158
+ }, {
159
+ source: 'Cart',
160
+ position: 'Checkout Button'
144
161
  });
145
162
  ```
146
163
 
@@ -156,6 +173,9 @@ await BytemTracker.trackPayOrder({
156
173
  { productId: 'prod_001', price: 99.99, quantity: 1 },
157
174
  { productId: 'prod_002', price: 50.01, quantity: 1 }
158
175
  ]
176
+ }, {
177
+ source: 'Checkout',
178
+ position: 'Pay Now'
159
179
  });
160
180
  ```
161
181
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytem/bytem-tracker-app",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "description": "Bytem Tracker SDK for React Native",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { TrackerConfig, Product, Order, UserTraits } from './types';
1
+ import { TrackerConfig, Product, Order, UserTraits, GoodsClickParams, TrackingParams } from './types';
2
2
  declare class BytemTracker {
3
3
  private static instance;
4
4
  private readonly SDK_NAME;
@@ -89,15 +89,7 @@ declare class BytemTracker {
89
89
  *
90
90
  * @param params - The parameters for the goods click event.
91
91
  */
92
- trackGoodsClick(params: {
93
- gid?: string;
94
- skuid?: string;
95
- url: string;
96
- source?: string;
97
- position?: string;
98
- current?: string;
99
- referrer?: string;
100
- }): Promise<void>;
92
+ trackGoodsClick(params: GoodsClickParams, customParams?: Record<string, any>): Promise<void>;
101
93
  private reportViewDuration;
102
94
  private getRealDeviceId;
103
95
  private getMetrics;
@@ -110,42 +102,43 @@ declare class BytemTracker {
110
102
  *
111
103
  * @param product - The product object to track.
112
104
  */
113
- trackViewProduct(product: Product): Promise<void>;
105
+ trackViewProduct(product: Product, params: TrackingParams): Promise<void>;
114
106
  /**
115
107
  * Tracks an add-to-cart event.
116
108
  *
117
109
  * @param product - The product added to cart.
110
+ * @param params - Additional parameters (current, source, position, etc.) or overrides.
118
111
  */
119
- trackAddToCart(product: Product): Promise<void>;
112
+ trackAddToCart(product: Product, params: TrackingParams): Promise<void>;
120
113
  /**
121
114
  * Track goods impression (e.g. collection page view)
122
115
  * @param products List of products displayed
123
- * @param source Source page/section
124
- * @param position Position in the list/page
116
+ * @param params Additional parameters (source, position, etc.) or overrides.
125
117
  */
126
- trackGoodsImpression(products: Product[], source?: string, position?: string): Promise<void>;
118
+ trackGoodsImpression(products: Product[], params: TrackingParams): Promise<void>;
127
119
  /**
128
120
  * Tracks an add-to-wishlist event.
129
121
  * @param product - The product added to wishlist.
122
+ * @param params - Additional parameters or overrides.
130
123
  */
131
- trackAddWishlist(product: Product): Promise<void>;
124
+ trackAddWishlist(product: Product, params: TrackingParams): Promise<void>;
132
125
  /**
133
126
  * Tracks a checkout order event.
134
127
  * Automatically splits product lists into parallel arrays (gid, price, quantity)
135
128
  * to match the backend requirement.
136
129
  *
137
130
  * @param order - The order object containing products to checkout.
138
- * @param source - Source page/section
139
- * @param position - Position info
131
+ * @param params - Additional parameters (source, position, etc.) or overrides.
140
132
  */
141
- trackCheckOutOrder(order: Order, source?: string, position?: string): Promise<void>;
133
+ trackCheckOutOrder(order: Order, params: TrackingParams): Promise<void>;
142
134
  /**
143
135
  * Tracks a payment order event.
144
136
  * Maps product list to a 'goods' array structure expected by the backend.
145
137
  *
146
138
  * @param order - The order object that was paid for.
139
+ * @param params - Additional parameters or overrides.
147
140
  */
148
- trackPayOrder(order: Order): Promise<void>;
141
+ trackPayOrder(order: Order, params: TrackingParams): Promise<void>;
149
142
  /**
150
143
  * Tracks user details/profile updates.
151
144
  *
@@ -431,25 +431,19 @@ class BytemTracker {
431
431
  *
432
432
  * @param params - The parameters for the goods click event.
433
433
  */
434
- async trackGoodsClick(params) {
434
+ async trackGoodsClick(params, customParams) {
435
435
  try {
436
436
  if (!this.checkInitialized())
437
437
  return;
438
- const segmentation = {
439
- gid: params.gid || '',
440
- skuid: params.skuid || '',
441
- url: params.url,
442
- current: params.current || '',
443
- referrer: params.referrer || '',
444
- visitor_id: this.visitorId || '',
445
- };
446
- if (this.appScheme)
447
- segmentation.domain = this.appScheme;
448
- if (params.source)
449
- segmentation.source = params.source;
450
- if (params.position)
451
- segmentation.position = params.position;
452
- await this.trackEvent('goods_click', segmentation); // Using string literal as Dart does in implementation
438
+ const finalParams = Object.assign({}, customParams);
439
+ if (this.appScheme && !finalParams.domain) {
440
+ finalParams.domain = this.appScheme;
441
+ }
442
+ if (this.visitorId && !finalParams.visitor_id) {
443
+ finalParams.visitor_id = this.visitorId;
444
+ }
445
+ const payload = Business.trackGoodsClick(params, finalParams);
446
+ await this.trackEvent(payload.event, payload.params);
453
447
  }
454
448
  catch (e) {
455
449
  if (this.debug)
@@ -588,20 +582,19 @@ class BytemTracker {
588
582
  *
589
583
  * @param product - The product object to track.
590
584
  */
591
- async trackViewProduct(product) {
585
+ async trackViewProduct(product, params) {
592
586
  try {
593
587
  if (!this.checkInitialized())
594
588
  return;
595
- // Map Product to segmentation
596
- const segmentation = {
597
- product_id: product.productId,
598
- name: product.name,
599
- price: product.price,
600
- currency: product.currency,
601
- category: product.category,
602
- };
603
- // In Dart, trackViewProduct sends "view_product" event.
604
- await this.trackEvent('view_product', segmentation);
589
+ const finalParams = Object.assign({}, params);
590
+ if (this.appScheme && !finalParams.domain) {
591
+ finalParams.domain = this.appScheme;
592
+ }
593
+ if (this.visitorId && !finalParams.visitor_id) {
594
+ finalParams.visitor_id = this.visitorId;
595
+ }
596
+ const payload = Business.trackViewProduct(product, finalParams);
597
+ await this.trackEvent(payload.event, payload.params);
605
598
  }
606
599
  catch (e) {
607
600
  if (this.debug)
@@ -612,21 +605,21 @@ class BytemTracker {
612
605
  * Tracks an add-to-cart event.
613
606
  *
614
607
  * @param product - The product added to cart.
608
+ * @param params - Additional parameters (current, source, position, etc.) or overrides.
615
609
  */
616
- async trackAddToCart(product) {
610
+ async trackAddToCart(product, params) {
617
611
  try {
618
612
  if (!this.checkInitialized())
619
613
  return;
620
- const segmentation = {
621
- gid: product.productId,
622
- name: product.name,
623
- price: product.price,
624
- currency: product.currency,
625
- category: product.category,
626
- quantity: product.quantity || 1,
627
- url: product.url,
628
- };
629
- await this.trackEvent('add_to_cart', segmentation);
614
+ const finalParams = Object.assign({}, params);
615
+ if (this.appScheme && !finalParams.domain) {
616
+ finalParams.domain = this.appScheme;
617
+ }
618
+ if (this.visitorId && !finalParams.visitor_id) {
619
+ finalParams.visitor_id = this.visitorId;
620
+ }
621
+ const payload = Business.trackAddToCart(product, finalParams);
622
+ await this.trackEvent(payload.event, payload.params);
630
623
  }
631
624
  catch (e) {
632
625
  if (this.debug)
@@ -636,14 +629,17 @@ class BytemTracker {
636
629
  /**
637
630
  * Track goods impression (e.g. collection page view)
638
631
  * @param products List of products displayed
639
- * @param source Source page/section
640
- * @param position Position in the list/page
632
+ * @param params Additional parameters (source, position, etc.) or overrides.
641
633
  */
642
- async trackGoodsImpression(products, source, position) {
634
+ async trackGoodsImpression(products, params) {
643
635
  try {
644
636
  if (!this.checkInitialized())
645
637
  return;
646
- const payload = Business.trackGoodsImpression(products, source, position);
638
+ const finalParams = Object.assign({}, params);
639
+ if (this.appScheme && !finalParams.domain) {
640
+ finalParams.domain = this.appScheme;
641
+ }
642
+ const payload = Business.trackGoodsImpression(products, finalParams);
647
643
  await this.trackEvent(payload.event, payload.params);
648
644
  }
649
645
  catch (e) {
@@ -654,12 +650,17 @@ class BytemTracker {
654
650
  /**
655
651
  * Tracks an add-to-wishlist event.
656
652
  * @param product - The product added to wishlist.
653
+ * @param params - Additional parameters or overrides.
657
654
  */
658
- async trackAddWishlist(product) {
655
+ async trackAddWishlist(product, params) {
659
656
  try {
660
657
  if (!this.checkInitialized())
661
658
  return;
662
- const payload = Business.trackAddWishlist(product);
659
+ const finalParams = Object.assign({}, params);
660
+ if (this.appScheme && !finalParams.domain) {
661
+ finalParams.domain = this.appScheme;
662
+ }
663
+ const payload = Business.trackAddWishlist(product, finalParams);
663
664
  await this.trackEvent(payload.event, payload.params);
664
665
  }
665
666
  catch (e) {
@@ -673,14 +674,17 @@ class BytemTracker {
673
674
  * to match the backend requirement.
674
675
  *
675
676
  * @param order - The order object containing products to checkout.
676
- * @param source - Source page/section
677
- * @param position - Position info
677
+ * @param params - Additional parameters (source, position, etc.) or overrides.
678
678
  */
679
- async trackCheckOutOrder(order, source, position) {
679
+ async trackCheckOutOrder(order, params) {
680
680
  try {
681
681
  if (!this.checkInitialized())
682
682
  return;
683
- const payload = Business.trackCheckOutOrder(order, source, position);
683
+ const finalParams = Object.assign({}, params);
684
+ if (this.appScheme && !finalParams.domain) {
685
+ finalParams.domain = this.appScheme;
686
+ }
687
+ const payload = Business.trackCheckOutOrder(order, finalParams);
684
688
  await this.trackEvent(payload.event, payload.params);
685
689
  }
686
690
  catch (e) {
@@ -693,26 +697,18 @@ class BytemTracker {
693
697
  * Maps product list to a 'goods' array structure expected by the backend.
694
698
  *
695
699
  * @param order - The order object that was paid for.
700
+ * @param params - Additional parameters or overrides.
696
701
  */
697
- async trackPayOrder(order) {
702
+ async trackPayOrder(order, params) {
698
703
  try {
699
704
  if (!this.checkInitialized())
700
705
  return;
701
- const segmentation = {
702
- order_id: order.orderId,
703
- total: order.total,
704
- currency: order.currency,
705
- };
706
- if (order.products && order.products.length > 0) {
707
- // Dart maps this to a list of maps called "goods"
708
- segmentation.goods = order.products.map(p => ({
709
- gid: p.productId,
710
- name: p.name,
711
- price: p.price,
712
- quantity: p.quantity || 1,
713
- }));
714
- }
715
- await this.trackEvent('pay_order', segmentation);
706
+ const finalParams = Object.assign({}, params);
707
+ if (this.appScheme && !finalParams.domain) {
708
+ finalParams.domain = this.appScheme;
709
+ }
710
+ const payload = Business.trackPayOrder(order, finalParams);
711
+ await this.trackEvent(payload.event, payload.params);
716
712
  }
717
713
  catch (e) {
718
714
  if (this.debug)
@@ -4,3 +4,4 @@ export * from './trackCheckOutOrder';
4
4
  export * from './trackPayOrder';
5
5
  export * from './trackGoodsImpression';
6
6
  export * from './trackAddWishlist';
7
+ export * from './trackGoodsClick';
@@ -20,3 +20,4 @@ __exportStar(require("./trackCheckOutOrder"), exports);
20
20
  __exportStar(require("./trackPayOrder"), exports);
21
21
  __exportStar(require("./trackGoodsImpression"), exports);
22
22
  __exportStar(require("./trackAddWishlist"), exports);
23
+ __exportStar(require("./trackGoodsClick"), exports);
@@ -1,2 +1,2 @@
1
- import { EventPayload, Product } from '../types';
2
- export declare const trackAddToCart: (product: Product) => EventPayload;
1
+ import { EventPayload, Product, TrackingParams } from '../types';
2
+ export declare const trackAddToCart: (product: Product, params: TrackingParams) => EventPayload;
@@ -1,18 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.trackAddToCart = void 0;
4
- const trackAddToCart = (product) => {
4
+ const trackAddToCart = (product, params) => {
5
+ const defaultParams = {
6
+ gid: product.productId,
7
+ name: product.name,
8
+ price: product.price,
9
+ currency: product.currency,
10
+ category: product.category,
11
+ quantity: product.quantity || 1,
12
+ url: product.url || '',
13
+ };
5
14
  return {
6
15
  event: 'add_to_cart',
7
- params: {
8
- gid: product.productId,
9
- name: product.name,
10
- price: product.price,
11
- currency: product.currency,
12
- category: product.category,
13
- quantity: product.quantity || 1,
14
- url: product.url,
15
- },
16
+ params: Object.assign(Object.assign({}, defaultParams), params),
16
17
  };
17
18
  };
18
19
  exports.trackAddToCart = trackAddToCart;
@@ -1,2 +1,2 @@
1
- import { EventPayload, Product } from '../types';
2
- export declare const trackAddWishlist: (product: Product) => EventPayload;
1
+ import { EventPayload, Product, TrackingParams } from '../types';
2
+ export declare const trackAddWishlist: (product: Product, params: TrackingParams) => EventPayload;
@@ -1,18 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.trackAddWishlist = void 0;
4
- const trackAddWishlist = (product) => {
4
+ const trackAddWishlist = (product, params) => {
5
+ const defaultParams = {
6
+ gid: product.productId,
7
+ name: product.name,
8
+ price: product.price,
9
+ currency: product.currency,
10
+ category: product.category,
11
+ quantity: product.quantity || 1,
12
+ url: product.url || '',
13
+ };
5
14
  return {
6
15
  event: 'add_wishlist',
7
- params: {
8
- gid: product.productId,
9
- name: product.name,
10
- price: product.price,
11
- currency: product.currency,
12
- category: product.category,
13
- quantity: product.quantity || 1,
14
- url: product.url,
15
- },
16
+ params: Object.assign(Object.assign({}, defaultParams), params),
16
17
  };
17
18
  };
18
19
  exports.trackAddWishlist = trackAddWishlist;
@@ -1,2 +1,2 @@
1
- import { EventPayload, Order } from '../types';
2
- export declare const trackCheckOutOrder: (order: Order, source?: string, position?: string) => EventPayload;
1
+ import { EventPayload, Order, TrackingParams } from '../types';
2
+ export declare const trackCheckOutOrder: (order: Order, params: TrackingParams) => EventPayload;
@@ -1,19 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.trackCheckOutOrder = void 0;
4
- const trackCheckOutOrder = (order, source, position) => {
4
+ const trackCheckOutOrder = (order, params) => {
5
+ const defaultParams = {
6
+ gid: order.products.map(p => p.productId),
7
+ url: order.products.map(p => p.url || ''),
8
+ price: order.products.map(p => p.price || 0),
9
+ quantity: order.products.map(p => p.quantity || 1),
10
+ amount: order.total,
11
+ currency: order.currency,
12
+ };
5
13
  return {
6
14
  event: 'check_out_order',
7
- params: {
8
- gid: order.products.map(p => p.productId),
9
- url: order.products.map(p => p.url || ''),
10
- price: order.products.map(p => p.price || 0),
11
- quantity: order.products.map(p => p.quantity || 1),
12
- amount: order.total,
13
- currency: order.currency,
14
- source: source || 'Other Page',
15
- position: position || ''
16
- },
15
+ params: Object.assign(Object.assign({}, defaultParams), params),
17
16
  };
18
17
  };
19
18
  exports.trackCheckOutOrder = trackCheckOutOrder;
@@ -0,0 +1,2 @@
1
+ import { EventPayload, GoodsClickParams } from '../types';
2
+ export declare const trackGoodsClick: (goodsParams: GoodsClickParams, params?: Record<string, any>) => EventPayload;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.trackGoodsClick = void 0;
4
+ const trackGoodsClick = (goodsParams, params) => {
5
+ const defaultParams = {
6
+ gid: goodsParams.gid,
7
+ skuid: goodsParams.skuid || '',
8
+ url: goodsParams.url || '',
9
+ current: goodsParams.current || '',
10
+ referrer: goodsParams.referrer || '',
11
+ source: goodsParams.source,
12
+ position: goodsParams.position,
13
+ };
14
+ return {
15
+ event: 'goods_click',
16
+ params: Object.assign(Object.assign({}, defaultParams), params),
17
+ };
18
+ };
19
+ exports.trackGoodsClick = trackGoodsClick;
@@ -1,2 +1,2 @@
1
- import { EventPayload, Product } from '../types';
2
- export declare const trackGoodsImpression: (products: Product[], source?: string, position?: string) => EventPayload;
1
+ import { EventPayload, Product, TrackingParams } from '../types';
2
+ export declare const trackGoodsImpression: (products: Product[], params: TrackingParams) => EventPayload;
@@ -1,22 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.trackGoodsImpression = void 0;
4
- const trackGoodsImpression = (products, source, position) => {
4
+ const trackGoodsImpression = (products, params) => {
5
5
  const gids = products.map(p => p.productId);
6
6
  const urls = products.map(p => p.url || '');
7
- // Currently Product doesn't have skuid, so we leave it empty or undefined?
8
- // dart/main.js: "skuid": skuids != null ? skuids : [],
7
+ const defaultParams = {
8
+ gid: gids,
9
+ skuid: [], // Empty for now as not in Product interface
10
+ urls: urls,
11
+ };
9
12
  return {
10
13
  event: 'goods_impression',
11
- params: {
12
- gid: gids,
13
- skuid: [], // Empty for now as not in Product interface
14
- urls: urls,
15
- source: source || 'Other Page', // Default from dart/main.js? line 7: source= 'Other Page'
16
- position: position || '',
17
- // visitor_id, ab, realab are handled by BytemTracker automatically or need to be passed?
18
- // BytemTracker usually handles common params like visitor_id.
19
- },
14
+ params: Object.assign(Object.assign({}, defaultParams), params),
20
15
  };
21
16
  };
22
17
  exports.trackGoodsImpression = trackGoodsImpression;
@@ -1,2 +1,2 @@
1
- import { EventPayload, Order } from '../types';
2
- export declare const trackPayOrder: (order: Order) => EventPayload;
1
+ import { EventPayload, Order, TrackingParams } from '../types';
2
+ export declare const trackPayOrder: (order: Order, params: TrackingParams) => EventPayload;
@@ -1,21 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.trackPayOrder = void 0;
4
- const trackPayOrder = (order) => {
4
+ const trackPayOrder = (order, params) => {
5
+ const defaultParams = {
6
+ order_id: order.orderId,
7
+ total: order.total,
8
+ currency: order.currency,
9
+ };
10
+ if (order.products && order.products.length > 0) {
11
+ // Maps to a list of maps called "goods" to match backend requirement
12
+ defaultParams.goods = order.products.map(p => ({
13
+ gid: p.productId,
14
+ name: p.name,
15
+ price: p.price,
16
+ quantity: p.quantity || 1,
17
+ }));
18
+ }
5
19
  return {
6
20
  event: 'pay_order',
7
- params: {
8
- order_id: order.orderId,
9
- total: order.total,
10
- currency: order.currency,
11
- products: order.products.map((p) => ({
12
- product_id: p.productId,
13
- name: p.name,
14
- price: p.price,
15
- quantity: p.quantity,
16
- })),
17
- status: 'success',
18
- },
21
+ params: Object.assign(Object.assign({}, defaultParams), params),
19
22
  };
20
23
  };
21
24
  exports.trackPayOrder = trackPayOrder;
@@ -1,2 +1,2 @@
1
- import { EventPayload, Product } from '../types';
2
- export declare const trackViewProduct: (product: Product) => EventPayload;
1
+ import { EventPayload, Product, TrackingParams } from '../types';
2
+ export declare const trackViewProduct: (product: Product, params: TrackingParams) => EventPayload;
@@ -1,16 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.trackViewProduct = void 0;
4
- const trackViewProduct = (product) => {
4
+ const trackViewProduct = (product, params) => {
5
+ const defaultParams = {
6
+ product_id: product.productId,
7
+ name: product.name,
8
+ price: product.price,
9
+ currency: product.currency,
10
+ category: product.category,
11
+ url: product.url || '',
12
+ };
5
13
  return {
6
14
  event: 'view_product',
7
- params: {
8
- product_id: product.productId,
9
- name: product.name,
10
- price: product.price,
11
- currency: product.currency,
12
- category: product.category,
13
- },
15
+ params: Object.assign(Object.assign({}, defaultParams), params),
14
16
  };
15
17
  };
16
18
  exports.trackViewProduct = trackViewProduct;
@@ -87,6 +87,21 @@ export interface Order {
87
87
  currency: string;
88
88
  products: Product[];
89
89
  }
90
+ export interface GoodsClickParams {
91
+ gid: string;
92
+ skuid?: string;
93
+ url?: string;
94
+ source: string;
95
+ position: string;
96
+ current?: string;
97
+ referrer?: string;
98
+ }
99
+ export interface TrackingParams {
100
+ current?: string;
101
+ source: string;
102
+ position: string;
103
+ [key: string]: any;
104
+ }
90
105
  export interface EventPayload {
91
106
  event: string;
92
107
  params: Record<string, any>;
@@ -210,6 +210,38 @@ describe('BytemTracker SDK', () => {
210
210
  beforeEach(async () => {
211
211
  await BytemTracker_1.default.init(mockConfig);
212
212
  });
213
+ it('should track add to cart with custom params and appScheme', async () => {
214
+ // Manually set appScheme since re-init is blocked by singleton check
215
+ // @ts-ignore
216
+ BytemTracker_1.default.appScheme = 'bytem.com';
217
+ const product = {
218
+ productId: 'prod_123',
219
+ name: 'Test Product',
220
+ price: 99.99,
221
+ currency: 'USD',
222
+ category: 'Electronics',
223
+ url: 'http://example.com/p/1'
224
+ };
225
+ const params = {
226
+ current: 'Product Detail Page',
227
+ source: 'Detail Page',
228
+ position: 'Add To Cart',
229
+ extra_key: 'extra_value'
230
+ };
231
+ await BytemTracker_1.default.trackAddToCart(product, params);
232
+ const calls = global.fetch.mock.calls;
233
+ const eventCall = calls.find(call => call[1].body && call[1].body.includes('events='));
234
+ const events = JSON.parse(new URLSearchParams(eventCall[1].body).get('events') || '[]');
235
+ expect(events[0].key).toBe('add_to_cart');
236
+ expect(events[0].segmentation).toMatchObject({
237
+ gid: 'prod_123',
238
+ name: 'Test Product',
239
+ current: 'Product Detail Page',
240
+ source: 'Detail Page',
241
+ position: 'Add To Cart',
242
+ extra_key: 'extra_value'
243
+ });
244
+ });
213
245
  it('should track checkout order', async () => {
214
246
  const order = {
215
247
  orderId: 'order_123',
@@ -220,7 +252,7 @@ describe('BytemTracker SDK', () => {
220
252
  { productId: 'prod_2', price: 49.99, quantity: 1 }
221
253
  ]
222
254
  };
223
- await BytemTracker_1.default.trackCheckOutOrder(order);
255
+ await BytemTracker_1.default.trackCheckOutOrder(order, { current: 'Checkout Page', source: 'Cart', position: 'Checkout' });
224
256
  const calls = global.fetch.mock.calls;
225
257
  const eventCall = calls.find(call => call[1].body && call[1].body.includes('events='));
226
258
  const events = JSON.parse(new URLSearchParams(eventCall[1].body).get('events') || '[]');
@@ -231,7 +263,8 @@ describe('BytemTracker SDK', () => {
231
263
  quantity: [1, 1],
232
264
  amount: 99.99,
233
265
  currency: 'USD',
234
- url: ['', '']
266
+ url: ['', ''],
267
+ current: 'Checkout Page'
235
268
  });
236
269
  });
237
270
  it('should track view product', async () => {
@@ -242,7 +275,7 @@ describe('BytemTracker SDK', () => {
242
275
  currency: 'USD',
243
276
  category: 'Electronics'
244
277
  };
245
- await BytemTracker_1.default.trackViewProduct(product);
278
+ await BytemTracker_1.default.trackViewProduct(product, { current: 'Product Page', source: 'List', position: 'Item' });
246
279
  const calls = global.fetch.mock.calls;
247
280
  const eventCall = calls.find(call => call[1].body && call[1].body.includes('events='));
248
281
  const events = JSON.parse(new URLSearchParams(eventCall[1].body).get('events') || '[]');
@@ -252,16 +285,26 @@ describe('BytemTracker SDK', () => {
252
285
  name: 'Test Product',
253
286
  price: 99.99,
254
287
  currency: 'USD',
255
- category: 'Electronics'
288
+ category: 'Electronics',
289
+ current: 'Product Page'
256
290
  });
257
291
  });
258
- it('should track goods click', async () => {
292
+ it('should track goods click with custom params', async () => {
293
+ // Manually set appScheme
294
+ // @ts-ignore
295
+ BytemTracker_1.default.appScheme = 'bytem.com';
259
296
  const params = {
260
297
  gid: 'goods_123',
261
298
  url: 'https://example.com/product/123',
262
- source: 'recommendation'
299
+ current: 'Product Page',
300
+ source: 'recommendation',
301
+ position: 'default_position'
263
302
  };
264
- await BytemTracker_1.default.trackGoodsClick(params);
303
+ const customParams = {
304
+ extra_key: 'extra_value',
305
+ position: 'custom_position'
306
+ };
307
+ await BytemTracker_1.default.trackGoodsClick(params, customParams);
265
308
  const calls = global.fetch.mock.calls;
266
309
  const eventCall = calls.find(call => call[1].body && call[1].body.includes('events='));
267
310
  const events = JSON.parse(new URLSearchParams(eventCall[1].body).get('events') || '[]');
@@ -269,7 +312,36 @@ describe('BytemTracker SDK', () => {
269
312
  expect(events[0].segmentation).toMatchObject({
270
313
  gid: 'goods_123',
271
314
  url: 'https://example.com/product/123',
272
- source: 'recommendation'
315
+ source: 'recommendation',
316
+ current: 'Product Page',
317
+ extra_key: 'extra_value',
318
+ position: 'custom_position'
319
+ });
320
+ // Verify visitor_id is present (in segmentation or base params, here it is in segmentation because of legacy logic)
321
+ expect(events[0].segmentation.visitor_id).toBeDefined();
322
+ });
323
+ it('should track goods click without url', async () => {
324
+ // Manually set appScheme
325
+ // @ts-ignore
326
+ BytemTracker_1.default.appScheme = 'bytem.com';
327
+ const params = {
328
+ gid: 'goods_123',
329
+ // url is omitted
330
+ current: 'Product Page',
331
+ source: 'recommendation',
332
+ position: 'default_position'
333
+ };
334
+ await BytemTracker_1.default.trackGoodsClick(params);
335
+ const calls = global.fetch.mock.calls;
336
+ const eventCall = calls.find(call => call[1].body && call[1].body.includes('events='));
337
+ const events = JSON.parse(new URLSearchParams(eventCall[1].body).get('events') || '[]');
338
+ expect(events[0].key).toBe('goods_click');
339
+ expect(events[0].segmentation).toMatchObject({
340
+ gid: 'goods_123',
341
+ url: '', // Should default to empty string
342
+ source: 'recommendation',
343
+ current: 'Product Page',
344
+ position: 'default_position'
273
345
  });
274
346
  });
275
347
  it('should track pay order', async () => {
@@ -282,7 +354,7 @@ describe('BytemTracker SDK', () => {
282
354
  { productId: 'prod_2', name: 'Product 2', price: 49.99, quantity: 2 }
283
355
  ]
284
356
  };
285
- await BytemTracker_1.default.trackPayOrder(order);
357
+ await BytemTracker_1.default.trackPayOrder(order, { current: 'Payment Page', source: 'Checkout', position: 'Pay Button' });
286
358
  const calls = global.fetch.mock.calls;
287
359
  const eventCall = calls.find(call => call[1].body && call[1].body.includes('events='));
288
360
  const events = JSON.parse(new URLSearchParams(eventCall[1].body).get('events') || '[]');
@@ -291,6 +363,7 @@ describe('BytemTracker SDK', () => {
291
363
  order_id: 'order_123',
292
364
  total: 99.99,
293
365
  currency: 'USD',
366
+ current: 'Payment Page',
294
367
  goods: [
295
368
  { gid: 'prod_1', name: 'Product 1', price: 50, quantity: 1 },
296
369
  { gid: 'prod_2', name: 'Product 2', price: 49.99, quantity: 2 }
@@ -30,7 +30,11 @@ describe('BytemTracker Add To Cart', () => {
30
30
  quantity: 2,
31
31
  url: 'https://example.com/product/p_1001'
32
32
  };
33
- await BytemTracker_1.default.trackAddToCart(product);
33
+ await BytemTracker_1.default.trackAddToCart(product, {
34
+ current: 'Product Detail Page',
35
+ source: 'Detail Page',
36
+ position: 'Add To Cart'
37
+ });
34
38
  expect(global.fetch).toHaveBeenCalled();
35
39
  const calls = global.fetch.mock.calls;
36
40
  const body = calls[calls.length - 1][1].body;
@@ -39,14 +43,17 @@ describe('BytemTracker Add To Cart', () => {
39
43
  const eventsJson = params.get('events');
40
44
  const events = JSON.parse(eventsJson);
41
45
  expect(events[0].key).toBe('add_to_cart');
42
- expect(events[0].segmentation).toEqual({
46
+ expect(events[0].segmentation).toMatchObject({
43
47
  gid: 'p_1001',
44
48
  name: 'Test Product',
45
49
  price: 99.99,
46
50
  currency: 'USD',
47
51
  category: 'Electronics',
48
52
  quantity: 2,
49
- url: 'https://example.com/product/p_1001'
53
+ url: 'https://example.com/product/p_1001',
54
+ current: 'Product Detail Page',
55
+ source: 'Detail Page',
56
+ position: 'Add To Cart'
50
57
  });
51
58
  });
52
59
  it('should use default quantity of 1 if not provided', async () => {
@@ -55,7 +62,11 @@ describe('BytemTracker Add To Cart', () => {
55
62
  name: 'Single Product',
56
63
  price: 10.00,
57
64
  };
58
- await BytemTracker_1.default.trackAddToCart(product);
65
+ await BytemTracker_1.default.trackAddToCart(product, {
66
+ current: 'Quick View',
67
+ source: 'Quick View',
68
+ position: 'Add Button'
69
+ });
59
70
  const calls = global.fetch.mock.calls;
60
71
  const body = calls[calls.length - 1][1].body;
61
72
  const params = new URLSearchParams(body);
@@ -9,6 +9,7 @@ global.fetch = jest.fn(() => Promise.resolve({
9
9
  ok: true,
10
10
  status: 200,
11
11
  json: () => Promise.resolve({ status: 'success' }),
12
+ text: () => Promise.resolve('{"status":"success"}'),
12
13
  }));
13
14
  describe('BytemTracker Additional Methods', () => {
14
15
  const mockConfig = {
@@ -27,7 +28,11 @@ describe('BytemTracker Additional Methods', () => {
27
28
  price: 50.00,
28
29
  url: 'https://example.com/wish'
29
30
  };
30
- await BytemTracker_1.default.trackAddWishlist(product);
31
+ await BytemTracker_1.default.trackAddWishlist(product, {
32
+ current: 'Product Detail Page',
33
+ source: 'Detail Page',
34
+ position: 'Wishlist Button'
35
+ });
31
36
  expect(global.fetch).toHaveBeenCalled();
32
37
  const calls = global.fetch.mock.calls;
33
38
  const body = calls[calls.length - 1][1].body;
@@ -51,7 +56,11 @@ describe('BytemTracker Additional Methods', () => {
51
56
  { productId: 'p_2', price: 50.00, quantity: 1, url: 'https://example.com/p2' }
52
57
  ]
53
58
  };
54
- await BytemTracker_1.default.trackCheckOutOrder(order, 'Cart Page', 'Checkout Button');
59
+ await BytemTracker_1.default.trackCheckOutOrder(order, {
60
+ current: 'Cart Page',
61
+ source: 'Cart Page',
62
+ position: 'Checkout Button'
63
+ });
55
64
  expect(global.fetch).toHaveBeenCalled();
56
65
  const calls = global.fetch.mock.calls;
57
66
  const body = calls[calls.length - 1][1].body;
@@ -41,6 +41,10 @@ describe('Debug Scenarios', () => {
41
41
  price: 699.00,
42
42
  currency: 'USD',
43
43
  category: 'Electronics'
44
+ }, {
45
+ current: 'Debug Page',
46
+ source: 'Debug List',
47
+ position: 'Item 1'
44
48
  });
45
49
  // Wait for async track
46
50
  await new Promise(resolve => setTimeout(resolve, 0));
@@ -60,6 +64,10 @@ describe('Debug Scenarios', () => {
60
64
  products: [
61
65
  { productId: 'p_1001', price: 699.00, quantity: 1 }
62
66
  ]
67
+ }, {
68
+ current: 'Checkout Page',
69
+ source: 'Cart Page',
70
+ position: 'Checkout Button'
63
71
  });
64
72
  await new Promise(resolve => setTimeout(resolve, 0));
65
73
  // Assertions to verify flow
@@ -32,7 +32,11 @@ describe('BytemTracker Goods Impression', () => {
32
32
  url: 'https://example.com/p2'
33
33
  }
34
34
  ];
35
- await BytemTracker_1.default.trackGoodsImpression(products, 'Collection Page', 'Top List');
35
+ await BytemTracker_1.default.trackGoodsImpression(products, {
36
+ current: 'Collection Page',
37
+ source: 'Collection Page',
38
+ position: 'Top List'
39
+ });
36
40
  expect(global.fetch).toHaveBeenCalled();
37
41
  const calls = global.fetch.mock.calls;
38
42
  const body = calls[calls.length - 1][1].body;
@@ -52,7 +56,11 @@ describe('BytemTracker Goods Impression', () => {
52
56
  const products = [
53
57
  { productId: 'p_3' }
54
58
  ];
55
- await BytemTracker_1.default.trackGoodsImpression(products);
59
+ await BytemTracker_1.default.trackGoodsImpression(products, {
60
+ current: 'Other Page',
61
+ source: 'Other Page',
62
+ position: 'List'
63
+ });
56
64
  expect(global.fetch).toHaveBeenCalled();
57
65
  const calls = global.fetch.mock.calls;
58
66
  const body = calls[calls.length - 1][1].body;
@@ -63,8 +71,8 @@ describe('BytemTracker Goods Impression', () => {
63
71
  expect(events[0].segmentation).toMatchObject({
64
72
  gid: ['p_3'],
65
73
  urls: [''], // Should default to empty string
66
- source: 'Other Page', // Default value
67
- position: '' // Default value
74
+ source: 'Other Page',
75
+ position: 'List'
68
76
  });
69
77
  });
70
78
  });
@@ -19,13 +19,6 @@ jest.mock('@react-native-async-storage/async-storage', () => ({
19
19
  return Promise.resolve(null);
20
20
  }),
21
21
  }));
22
- // Mock React Native Device Info
23
- jest.mock('react-native-device-info', () => ({
24
- getSystemName: jest.fn(() => 'iOS'),
25
- getSystemVersion: jest.fn(() => '14.0'),
26
- getModel: jest.fn(() => 'iPhone 11'),
27
- getUserAgent: jest.fn(() => Promise.resolve('Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)')),
28
- }), { virtual: true });
29
22
  // Mock React Native
30
23
  jest.mock('react-native', () => ({
31
24
  Platform: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytem/bytem-tracker-app",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "description": "Bytem Tracker SDK for React Native",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -1,2 +0,0 @@
1
- import { EventPayload, UserTraits } from '../types';
2
- export declare const trackUser: (userId: string, traits?: UserTraits) => EventPayload;
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.trackUser = void 0;
4
- const trackUser = (userId, traits = {}) => {
5
- return {
6
- event: 'identify',
7
- params: {
8
- user_id: userId,
9
- traits: traits,
10
- },
11
- };
12
- };
13
- exports.trackUser = trackUser;