react-native-edgee 1.0.8 → 1.0.10

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
@@ -1,4 +1,4 @@
1
- # react-native-edgee
1
+ # Edgee data collection sdk for React Native
2
2
 
3
3
  For React Native applications, we provide a comprehensive SDK that enables
4
4
  seamless data collection with rich native context. This SDK automatically
package/dist/api.d.ts CHANGED
@@ -27,6 +27,12 @@ export type EdgeeEvent = {
27
27
  components: Record<string, boolean> | undefined;
28
28
  context: EdgeeFullContext;
29
29
  };
30
+ export type ConsentEvent = {
31
+ type: "consent";
32
+ status: "granted" | "denied" | "pending";
33
+ };
34
+ export type QueueItem = EdgeeEvent | ConsentEvent;
35
+ export declare const isConsentEvent: (item: QueueItem) => item is ConsentEvent;
30
36
  export declare const createScreenEvent: (data: EdgeeScreenEvent, components: Record<string, boolean> | undefined, context: EdgeeFullContext) => EdgeeEvent;
31
37
  export declare const createTrackEvent: (data: EdgeeTrackEvent, components: Record<string, boolean> | undefined, context: EdgeeFullContext) => EdgeeEvent;
32
38
  export declare const createUserEvent: (data: EdgeeUserEvent, components: Record<string, boolean> | undefined, context: EdgeeFullContext) => EdgeeEvent;
@@ -38,4 +44,12 @@ export declare const sendPayload: (config: EdgeeConfig, payload: any) => Promise
38
44
  * Sends an event to the Edgee API
39
45
  */
40
46
  export declare const uploadEvent: (config: EdgeeConfig, event: EdgeeEvent) => Promise<void>;
47
+ /**
48
+ * Sends a consent event to the Edgee API
49
+ */
50
+ export declare const uploadConsent: (config: EdgeeConfig, consent: ConsentEvent) => Promise<void>;
51
+ /**
52
+ * Creates a consent event
53
+ */
54
+ export declare const createConsentEvent: (status: "granted" | "denied" | "pending") => ConsentEvent;
41
55
  export {};
package/dist/api.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uploadEvent = exports.sendPayload = exports.createUserEvent = exports.createTrackEvent = exports.createScreenEvent = void 0;
3
+ exports.createConsentEvent = exports.uploadConsent = exports.uploadEvent = exports.sendPayload = exports.createUserEvent = exports.createTrackEvent = exports.createScreenEvent = exports.isConsentEvent = void 0;
4
4
  const edgee_store_1 = require("./core/edgee-store");
5
5
  const utils_1 = require("./core/utils");
6
6
  var EventType;
@@ -9,6 +9,11 @@ var EventType;
9
9
  EventType["User"] = "user";
10
10
  EventType["Screen"] = "screen";
11
11
  })(EventType || (EventType = {}));
12
+ // Type guard to check if item is a consent event
13
+ const isConsentEvent = (item) => {
14
+ return item.type === "consent";
15
+ };
16
+ exports.isConsentEvent = isConsentEvent;
12
17
  const createScreenEvent = (data, components, context) => {
13
18
  return {
14
19
  type: EventType.Track,
@@ -129,6 +134,29 @@ const uploadEvent = async (config, event) => {
129
134
  return;
130
135
  };
131
136
  exports.uploadEvent = uploadEvent;
137
+ /**
138
+ * Sends a consent event to the Edgee API
139
+ */
140
+ const uploadConsent = async (config, consent) => {
141
+ const payload = {
142
+ data_collection: {
143
+ consent: consent.status,
144
+ },
145
+ };
146
+ await (0, exports.sendPayload)(config, payload);
147
+ return;
148
+ };
149
+ exports.uploadConsent = uploadConsent;
150
+ /**
151
+ * Creates a consent event
152
+ */
153
+ const createConsentEvent = (status) => {
154
+ return {
155
+ type: "consent",
156
+ status,
157
+ };
158
+ };
159
+ exports.createConsentEvent = createConsentEvent;
132
160
  /**
133
161
  * Handles response data: stores IDs, handles cookies, and logs events
134
162
  * Similar to the JS SDK handleResponse function
@@ -1,8 +1,8 @@
1
- import { EdgeeEvent } from "../api";
1
+ import { QueueItem } from "../api";
2
2
  export declare class EdgeeStore {
3
3
  edgeeId: string | null;
4
4
  userId: string | null;
5
- pendingEvents: EdgeeEvent[];
5
+ pendingEvents: QueueItem[];
6
6
  initialized: boolean;
7
7
  constructor();
8
8
  init(): Promise<void>;
@@ -14,8 +14,8 @@ export declare class EdgeeStore {
14
14
  edgeeId: string | null;
15
15
  userId: string | null;
16
16
  }>;
17
- addEvent(event: EdgeeEvent): Promise<void>;
18
- getPendingEvents(): Promise<EdgeeEvent[]>;
17
+ addEvent(event: QueueItem): Promise<void>;
18
+ getPendingEvents(): Promise<QueueItem[]>;
19
19
  clearEvents(): Promise<void>;
20
20
  reset(): Promise<void>;
21
21
  }
@@ -1,5 +1,5 @@
1
1
  import { EdgeeConfig } from "..";
2
- import { EdgeeEvent } from "../api";
2
+ import { QueueItem } from "../api";
3
3
  export declare class EventQueue {
4
4
  private config;
5
5
  private q;
@@ -10,12 +10,7 @@ export declare class EventQueue {
10
10
  constructor(config: EdgeeConfig);
11
11
  destroy(): void;
12
12
  setReady(val: boolean): void;
13
- enqueue(item: EdgeeEvent): void;
14
- /**
15
- * Send a direct payload (used for consent events)
16
- * This bypasses the normal event structure and sends raw payload
17
- */
18
- sendEvent(payload: any): Promise<void>;
13
+ enqueue(item: QueueItem): void;
19
14
  private shouldFlush;
20
15
  flush(): Promise<void>;
21
16
  }
@@ -25,8 +25,14 @@ class EventQueue {
25
25
  this.online = !!state.isConnected && !!state.isInternetReachable;
26
26
  });
27
27
  void edgee_store_1.edgeeStore.getPendingEvents().then((events) => {
28
- this.q = events;
28
+ // Merge persisted events with any events that were added during initialization
29
+ // to avoid losing events due to race conditions
30
+ const existingEvents = this.q;
31
+ this.q = [...events, ...existingEvents];
29
32
  this.ready = true;
33
+ // Trigger flush now that we're ready
34
+ if (this.shouldFlush())
35
+ void this.flush();
30
36
  });
31
37
  }
32
38
  destroy() {
@@ -41,51 +47,46 @@ class EventQueue {
41
47
  enqueue(item) {
42
48
  this.q.push(item);
43
49
  void edgee_store_1.edgeeStore.addEvent(item);
44
- if (this.shouldFlush())
50
+ if (this.shouldFlush()) {
45
51
  void this.flush();
46
- }
47
- /**
48
- * Send a direct payload (used for consent events)
49
- * This bypasses the normal event structure and sends raw payload
50
- */
51
- async sendEvent(payload) {
52
- if (!this.online) {
53
- // For direct payloads, we can't easily queue them in the current structure
54
- // So we'll send them when we come back online
55
- return;
56
- }
57
- try {
58
- await (0, api_1.sendPayload)(this.config, payload);
59
- }
60
- catch (error) {
61
- (0, utils_1.logError)("[Queue] Error sending event.", error);
62
- throw error;
63
52
  }
64
53
  }
65
54
  shouldFlush() {
66
55
  return this.ready && this.online && this.q.length > 0;
67
56
  }
68
57
  async flush() {
69
- if (this.flushing || !this.shouldFlush())
58
+ if (this.flushing || !this.shouldFlush()) {
70
59
  return;
60
+ }
71
61
  this.flushing = true;
72
- const items = [...this.q];
62
+ // Take items from the queue atomically using splice
63
+ // This prevents losing events that are added during flush
64
+ const itemsToFlush = this.q.splice(0, this.q.length);
65
+ (0, utils_1.log)(this.config, `Flushing ${itemsToFlush.length} event(s)...`);
73
66
  try {
74
- for (const item of items) {
75
- await (0, api_1.uploadEvent)(this.config, item);
67
+ for (const item of itemsToFlush) {
68
+ if ((0, api_1.isConsentEvent)(item)) {
69
+ await (0, api_1.uploadConsent)(this.config, item);
70
+ (0, utils_1.log)(this.config, `Consent sent: ${item.status}`);
71
+ }
72
+ else {
73
+ await (0, api_1.uploadEvent)(this.config, item);
74
+ (0, utils_1.log)(this.config, `Event sent: ${item.type} - ${item.data.name || "user"}`);
75
+ }
76
76
  }
77
- this.q = [];
77
+ // Only clear persisted events after successful send
78
78
  await edgee_store_1.edgeeStore.clearEvents();
79
79
  }
80
80
  catch (error) {
81
81
  (0, utils_1.logError)("Error processing event batch.", error);
82
- this.q = [];
83
- await edgee_store_1.edgeeStore.clearEvents();
82
+ // On error, re-add failed items to the front of the queue for retry
83
+ this.q.unshift(...itemsToFlush);
84
84
  }
85
85
  finally {
86
86
  this.flushing = false;
87
+ // Drain any events that were added during flush
87
88
  if (this.shouldFlush())
88
- void this.flush(); // Drain if new items arrived
89
+ void this.flush();
89
90
  }
90
91
  }
91
92
  }
package/dist/index.d.ts CHANGED
@@ -27,7 +27,7 @@ export declare class EdgeeClient {
27
27
  */
28
28
  user(data: EdgeeUserEvent, components?: Components): Promise<void>;
29
29
  /**
30
- * Send consent event directly to Edgee (matches web SDK format)
30
+ * Send consent event to Edgee (queued like other events)
31
31
  */
32
32
  consent(status: ConsentStatus): Promise<void>;
33
33
  setConsent(status: ConsentStatus): Promise<void>;
package/dist/index.js CHANGED
@@ -64,6 +64,7 @@ class EdgeeClient {
64
64
  }
65
65
  const event = (0, api_1.createScreenEvent)(restData, components, context);
66
66
  this.queue.enqueue(event);
67
+ (0, utils_1.log)(this.config, "SCREEN event queued:", screen_name);
67
68
  }
68
69
  /**
69
70
  * Track a custom event
@@ -83,6 +84,7 @@ class EdgeeClient {
83
84
  }
84
85
  const event = (0, api_1.createTrackEvent)(restData, components, context);
85
86
  this.queue.enqueue(event);
87
+ (0, utils_1.log)(this.config, "TRACK event queued:", data.name);
86
88
  }
87
89
  /**
88
90
  * Track a user event
@@ -91,9 +93,10 @@ class EdgeeClient {
91
93
  const context = await (0, context_1.getContext)(this.config);
92
94
  const event = (0, api_1.createUserEvent)(data, components, context);
93
95
  this.queue.enqueue(event);
96
+ (0, utils_1.log)(this.config, "USER event queued:", data.user_id || data.anonymous_id || "anonymous");
94
97
  }
95
98
  /**
96
- * Send consent event directly to Edgee (matches web SDK format)
99
+ * Send consent event to Edgee (queued like other events)
97
100
  */
98
101
  async consent(status) {
99
102
  // Validate consent status
@@ -103,20 +106,10 @@ class EdgeeClient {
103
106
  }
104
107
  // Store consent locally
105
108
  await consent_1.edgeeConsent.setConsent(status);
106
- // Send consent event using web SDK format
107
- const payload = {
108
- data_collection: {
109
- consent: status,
110
- },
111
- };
112
- try {
113
- await this.queue.sendEvent(payload);
114
- (0, utils_1.log)(this.config, "- Consent set to:", status);
115
- }
116
- catch (error) {
117
- (0, utils_1.logError)("Error collecting consent event", error);
118
- throw error;
119
- }
109
+ // Queue consent event (will be sent when online)
110
+ const event = (0, api_1.createConsentEvent)(status);
111
+ this.queue.enqueue(event);
112
+ (0, utils_1.log)(this.config, "- Consent queued:", status);
120
113
  }
121
114
  // Consent management methods
122
115
  async setConsent(status) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-edgee",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Lightweight Edgee data collection client for React Native with native context collection.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",