react-native-edgee 1.0.5 → 1.0.7

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
@@ -126,7 +126,7 @@ import { EdgeeClient } from 'react-native-edgee';
126
126
  // Create client instance
127
127
  export const edgee = new EdgeeClient({
128
128
  host: "https://your-edgee-host.com",
129
- debug: __DEV__, // Enable debug logging in development
129
+ debug: false, // Set to true if you want to enable debugging
130
130
  collectDeviceId: false, // Set to true if you need unique device tracking
131
131
  });
132
132
  ```
@@ -134,24 +134,32 @@ export const edgee = new EdgeeClient({
134
134
  ### Track Events
135
135
 
136
136
  ```typescript
137
- // Track events (automatically includes rich native context)
138
- // Consent is handled transparently - no need to check before each call!
139
- edgee.track('App Launched', {
140
- source: 'cold_start',
141
- version: '1.0.0'
137
+ // Track screen views
138
+ edgee.screen({
139
+ screen_name: 'Home Screen',
140
+ screen_class: '/',
141
+ properties: {
142
+ category: 'main',
143
+ loaded_time: Date.now()
144
+ }
142
145
  });
143
146
 
144
- // Track user information
145
- edgee.user({
146
- id: '123',
147
- email: 'user@example.com',
148
- plan: 'premium'
147
+ // Track events
148
+ edgee.track({
149
+ name: 'App Launched', // event name
150
+ properties: {
151
+ source: 'cold_start',
152
+ version: '1.0.0'
153
+ }
149
154
  });
150
155
 
151
- // Track screen views
152
- edgee.screen('Home Screen', {
153
- category: 'main',
154
- loaded_time: Date.now()
156
+ // Track user information
157
+ edgee.user({
158
+ user_id: '123',
159
+ properties: {
160
+ email: 'user@example.com',
161
+ plan: 'premium'
162
+ }
155
163
  });
156
164
  ```
157
165
 
@@ -159,11 +167,10 @@ edgee.screen('Home Screen', {
159
167
 
160
168
  ```typescript
161
169
  // Set consent - all tracking calls automatically respect this setting
162
- await edgee.setConsent('granted'); // 'granted', 'denied', or 'pending'
170
+ await edgee.consent('granted'); // 'granted', 'denied', or 'pending'
163
171
 
164
172
  // Check consent status
165
173
  console.log('Current consent:', edgee.getConsent());
166
- console.log('Can track:', edgee.canTrack());
167
174
 
168
175
  // Listen for consent changes
169
176
  const unsubscribe = edgee.onConsentChange((status) => {
@@ -200,98 +207,6 @@ With native modules enabled, each event automatically includes comprehensive con
200
207
  - Memory usage, storage info
201
208
  - Battery level and state (iOS)
202
209
 
203
- ### Network Information
204
- - Connection type (WiFi, cellular, ethernet)
205
- - Carrier name and network codes
206
- - Radio technology (3G, 4G, 5G)
207
-
208
- ### Privacy Information *(Optional)*
209
- - Advertising ID (with proper consent on iOS 14+)
210
- - Device ID (privacy-compliant, opt-in only)
211
- - Tracking authorization status
212
-
213
- ## ⚛️ React Integration
214
-
215
- ### Context Provider (Optional)
216
-
217
- ```typescript
218
- import { EdgeeProvider, useEdgee } from 'react-native-edgee';
219
-
220
- // Wrap your app
221
- export default function App() {
222
- return (
223
- <EdgeeProvider host="https://your-edgee-host.com" debug={__DEV__}>
224
- <YourApp />
225
- </EdgeeProvider>
226
- );
227
- }
228
-
229
- // Use in components
230
- function SomeComponent() {
231
- const edgee = useEdgee();
232
-
233
- const handleButtonPress = () => {
234
- // Tracking automatically respects consent - no need to check!
235
- edgee.track('Button Pressed', { button_id: 'cta_main' });
236
- };
237
-
238
- const handleConsentGrant = async () => {
239
- await edgee.setConsent('granted');
240
- };
241
-
242
- return (
243
- <View>
244
- <Button onPress={handleButtonPress} title="Track Me" />
245
- <Button onPress={handleConsentGrant} title="Grant Consent" />
246
- </View>
247
- );
248
- }
249
- ```
250
-
251
- ### Auto Screen Tracking
252
-
253
- <details>
254
- <summary><strong>Expo Router</strong></summary>
255
-
256
- ```typescript
257
- import { EdgeeAutoTracker } from 'react-native-edgee';
258
-
259
- export default function RootLayout() {
260
- return (
261
- <>
262
- <EdgeeAutoTracker edgee={edgee} />
263
- <Stack>
264
- <Stack.Screen name="index" />
265
- <Stack.Screen name="profile" />
266
- </Stack>
267
- </>
268
- );
269
- }
270
- ```
271
-
272
- </details>
273
-
274
- <details>
275
- <summary><strong>React Navigation</strong></summary>
276
-
277
- ```typescript
278
- import { navigation } from 'react-native-edgee';
279
-
280
- const navigationRef = useRef();
281
-
282
- return (
283
- <NavigationContainer
284
- ref={navigationRef}
285
- onStateChange={() => {
286
- navigation.trackScreenChange(navigationRef, edgee);
287
- }}
288
- >
289
- {/* Your navigation structure */}
290
- </NavigationContainer>
291
- );
292
- ```
293
-
294
- </details>
295
210
 
296
211
  ## ⚙️ Configuration
297
212
 
@@ -300,88 +215,61 @@ interface EdgeeConfig {
300
215
  host: string; // Your Edgee endpoint URL (required)
301
216
  debug?: boolean; // Enable debug logging (default: false)
302
217
  collectDeviceId?: boolean; // Collect unique device ID (default: false)
218
+ cookieName?: string // Name of the cookie used by Edgee (it must be identical to the one on the console. Do not change it if you are unsure).
303
219
  }
304
220
  ```
305
221
 
306
- ### Privacy Considerations
307
-
308
- - **Device ID Collection**: Only enable `collectDeviceId: true` if you need persistent device tracking
309
- - **iOS Advertising ID**: Automatically respects App Tracking Transparency (iOS 14+)
310
- - **GDPR/CCPA Compliance**: All sensitive data collection is optional and clearly documented
311
-
312
- ## 🔧 Advanced Usage
313
-
314
- ### Manual Native Context Access
315
-
316
- ```typescript
317
- import { getNativeContext, isNativeModuleAvailable } from 'react-native-edgee';
318
-
319
- // Check if native modules are available
320
- if (isNativeModuleAvailable()) {
321
- const context = await getNativeContext({ collectDeviceId: false });
322
- console.log('Device model:', context.model);
323
- console.log('Is tablet:', context.isTablet);
324
- console.log('Network type:', context.networkType);
325
- console.log('Total memory:', context.totalMemoryMB);
326
- }
327
- ```
328
-
329
- ### Context Caching
330
-
331
- ```typescript
332
- import { clearContextCache } from 'react-native-edgee';
333
222
 
334
- // Clear cached context (useful for testing or when context might change)
335
- clearContextCache();
336
- ```
223
+ ## 🧪 Testing with EdgeeTestApp
337
224
 
338
- ## 🔍 Troubleshooting
225
+ The repository includes a test app (`EdgeeTestApp/`) that allows you to quickly test the SDK functionality without integrating it into your own app.
339
226
 
340
- ### Common Issues
227
+ ### Running the Test App
341
228
 
342
- <details>
343
- <summary><strong>"Module not found" Error</strong></summary>
229
+ 1. **Navigate to the test app directory:**
230
+ ```bash
231
+ cd EdgeeTestApp
232
+ ```
344
233
 
345
- **iOS:**
346
- ```bash
347
- cd ios && rm -rf build && pod install && cd ..
348
- npx react-native run-ios
349
- ```
234
+ 2. **Install dependencies:**
235
+ ```bash
236
+ npm install
237
+ # or
238
+ yarn install
239
+ ```
350
240
 
351
- **Android:**
352
- - Ensure `EdgeeReactNativePackage` is added to `MainApplication.java`
353
- - Clean build: `cd android && ./gradlew clean && cd ..`
241
+ 3. **For iOS - Install pods:**
242
+ ```bash
243
+ cd ios && pod install && cd ..
244
+ ```
354
245
 
355
- </details>
246
+ 4. **Start Metro bundler:**
247
+ ```bash
248
+ npm start
249
+ # or
250
+ yarn start
251
+ ```
356
252
 
357
- <details>
358
- <summary><strong>No Native Context in Events</strong></summary>
253
+ Then type i to launch an iOS app, or a for Android
359
254
 
360
- 1. Check if native modules are available:
361
- ```typescript
362
- console.log('Available:', isNativeModuleAvailable());
363
- ```
255
+ ### Using the Test App
364
256
 
365
- 2. If `false`, verify platform setup above
366
- 3. In Expo Go, this is expected (use Expo Development Build)
257
+ The test app provides a simple UI to test all SDK features:
367
258
 
368
- </details>
259
+ 1. **Set Edgee Host**: Enter your Edgee endpoint URL (defaults to `https://demo.edgee.app`)
260
+ - Click "Init" to initialize the SDK with your host
369
261
 
370
- <details>
371
- <summary><strong>Build Errors</strong></summary>
262
+ 2. **Test Events**:
263
+ - **Track Event**: Enter an event name and click "Track Event" to send a track event
264
+ - **Screen Event**: Click "Screen Event" to track a screen view
265
+ - **User Event**: Click "User Event" to send user identification data
372
266
 
373
- **Clean everything:**
374
- ```bash
375
- # React Native CLI
376
- cd ios && rm -rf build && cd ..
377
- cd android && ./gradlew clean && cd ..
378
- npx react-native start --reset-cache
267
+ 3. **Test Consent Management**:
268
+ - Click "Pending", "Granted", or "Denied" to set consent status
269
+ - Click "Get Consent" to view the current consent status
379
270
 
380
- # Expo
381
- npx expo run:ios --clear-cache
382
- ```
271
+ 4. **Monitor Status**: The status bar at the bottom shows the result of each action
383
272
 
384
- </details>
385
273
 
386
274
  ### Debug Mode
387
275
 
@@ -423,4 +311,4 @@ MIT
423
311
  ## 🆘 Support
424
312
 
425
313
  - **Issues**: [GitHub Issues](https://github.com/edgee-cloud/react-native-edgee/issues)
426
- - **Documentation**: [Edgee Docs](https://docs.edgee.cloud)
314
+ - **Documentation**: [Edgee Docs](https://www.edgee.cloud/docs)
package/dist/api.d.ts CHANGED
@@ -6,27 +6,36 @@ declare enum EventType {
6
6
  Screen = "screen"
7
7
  }
8
8
  export type EdgeeTrackEvent = {
9
- type: EventType.Track;
10
9
  name: string;
11
- components: Record<string, boolean> | undefined;
12
- data: object;
13
- context: EdgeeFullContext;
10
+ screen_name?: string;
11
+ screen_class?: string;
12
+ properties?: object;
14
13
  };
15
14
  export type EdgeeUserEvent = {
16
- type: EventType.User;
17
- data: object;
18
- components: Record<string, boolean> | undefined;
19
- context: EdgeeFullContext;
15
+ user_id?: string;
16
+ anonymous_id?: string;
17
+ properties?: object;
20
18
  };
21
19
  export type EdgeeScreenEvent = {
22
- type: EventType.Screen;
23
- name: string;
20
+ screen_name: string;
21
+ screen_class?: string;
22
+ properties?: object;
23
+ };
24
+ export type EdgeeEvent = {
25
+ type: EventType.Track | EventType.User | EventType.Screen;
24
26
  data: object;
25
27
  components: Record<string, boolean> | undefined;
26
28
  context: EdgeeFullContext;
27
29
  };
28
- export type EdgeeEvent = EdgeeTrackEvent | EdgeeUserEvent | EdgeeScreenEvent;
29
- export declare const createTrackEvent: (params: Omit<EdgeeTrackEvent, "type">) => EdgeeTrackEvent;
30
- export declare const createUserEvent: (params: Omit<EdgeeUserEvent, "type">) => EdgeeUserEvent;
31
- export declare const uploadEvent: (url: string, config: EdgeeConfig, event: EdgeeEvent) => Promise<Response>;
30
+ export declare const createScreenEvent: (data: EdgeeScreenEvent, components: Record<string, boolean> | undefined, context: EdgeeFullContext) => EdgeeEvent;
31
+ export declare const createTrackEvent: (data: EdgeeTrackEvent, components: Record<string, boolean> | undefined, context: EdgeeFullContext) => EdgeeEvent;
32
+ export declare const createUserEvent: (data: EdgeeUserEvent, components: Record<string, boolean> | undefined, context: EdgeeFullContext) => EdgeeEvent;
33
+ /**
34
+ * Sends a payload to the Edgee API with proper headers and handles the response
35
+ */
36
+ export declare const sendPayload: (config: EdgeeConfig, payload: any) => Promise<void>;
37
+ /**
38
+ * Sends an event to the Edgee API
39
+ */
40
+ export declare const uploadEvent: (config: EdgeeConfig, event: EdgeeEvent) => Promise<void>;
32
41
  export {};
package/dist/api.js CHANGED
@@ -1,111 +1,165 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uploadEvent = exports.createUserEvent = exports.createTrackEvent = void 0;
3
+ exports.uploadEvent = exports.sendPayload = exports.createUserEvent = exports.createTrackEvent = exports.createScreenEvent = void 0;
4
+ const edgee_store_1 = require("./core/edgee-store");
5
+ const utils_1 = require("./core/utils");
4
6
  var EventType;
5
7
  (function (EventType) {
6
8
  EventType["Track"] = "track";
7
9
  EventType["User"] = "user";
8
10
  EventType["Screen"] = "screen";
9
11
  })(EventType || (EventType = {}));
10
- const createTrackEvent = (params) => {
12
+ const createScreenEvent = (data, components, context) => {
11
13
  return {
12
14
  type: EventType.Track,
13
- ...params,
15
+ data: {
16
+ name: "screen_view",
17
+ ...data,
18
+ },
19
+ components,
20
+ context: context,
21
+ };
22
+ };
23
+ exports.createScreenEvent = createScreenEvent;
24
+ const createTrackEvent = (data, components, context) => {
25
+ return {
26
+ type: EventType.Track,
27
+ data,
28
+ components,
29
+ context: context,
14
30
  };
15
31
  };
16
32
  exports.createTrackEvent = createTrackEvent;
17
- const createUserEvent = (params) => {
33
+ const createUserEvent = (data, components, context) => {
18
34
  return {
19
35
  type: EventType.User,
20
- ...params,
36
+ data,
37
+ components,
38
+ context: context,
21
39
  };
22
40
  };
23
41
  exports.createUserEvent = createUserEvent;
24
- const uploadEvent = async (url, config, event) => {
25
- const eventToSend = event;
26
- if (eventToSend.type === "track") {
27
- const event = {
28
- data_collection: {
29
- context: eventToSend.context,
30
- events: [
31
- {
32
- type: "track",
33
- data: {
34
- name: eventToSend.name,
35
- properties: eventToSend.data,
36
- },
37
- components: eventToSend.components,
38
- },
39
- ],
40
- },
41
- };
42
- if (config.debug) {
43
- // eslint-disable-next-line no-console
44
- console.log("[Edgee RN] sending", { url, event });
42
+ /**
43
+ * Builds the event payload structure for API requests
44
+ */
45
+ const buildEventPayload = (event) => {
46
+ const basePayload = {
47
+ data_collection: {
48
+ context: event.context,
49
+ events: [],
50
+ },
51
+ };
52
+ basePayload.data_collection.events.push({
53
+ type: event.type,
54
+ data: event.data,
55
+ components: event.components,
56
+ });
57
+ return basePayload;
58
+ };
59
+ /**
60
+ * Builds the Edgee-Cookie header string from edgeeId and userId
61
+ * Similar to the JS SDK cookie reconstruction logic
62
+ */
63
+ const buildCookieHeader = async (config) => {
64
+ const cookies = [];
65
+ const { edgeeId, userId } = await edgee_store_1.edgeeStore.getContext();
66
+ if (edgeeId) {
67
+ cookies.push(`${config.cookieName}=${edgeeId}`);
68
+ }
69
+ if (userId) {
70
+ cookies.push(`${config.cookieName}_u=${userId}`);
71
+ }
72
+ return cookies.length > 0 ? cookies.join("; ") : undefined;
73
+ };
74
+ /**
75
+ * Builds headers for API requests including Edgee-Cookie header
76
+ */
77
+ const buildHeaders = async (config) => {
78
+ const headers = {
79
+ "Content-Type": "application/json",
80
+ };
81
+ if (config.debug) {
82
+ headers["Edgee-Debug"] = "1";
83
+ }
84
+ // Build and add Edgee-Cookie header from store
85
+ const cookieHeader = await buildCookieHeader(config);
86
+ if (cookieHeader) {
87
+ headers["Edgee-Cookie"] = cookieHeader;
88
+ }
89
+ else {
90
+ headers["Edgee-Cookie"] = "";
91
+ }
92
+ return headers;
93
+ };
94
+ /**
95
+ * Sends a payload to the Edgee API with proper headers and handles the response
96
+ */
97
+ const sendPayload = async (config, payload) => {
98
+ const headers = await buildHeaders(config);
99
+ const url = `${config.host}/_edgee/event`;
100
+ const response = await fetch(url, {
101
+ method: "POST",
102
+ headers,
103
+ body: JSON.stringify(payload),
104
+ });
105
+ try {
106
+ const text = await response.text().catch(() => "");
107
+ if (text) {
108
+ try {
109
+ const data = JSON.parse(text);
110
+ await handleResponse(data, config);
111
+ }
112
+ catch (parseError) {
113
+ (0, utils_1.logError)("[Debug] Parsing response from Fetch to JSON failed.", parseError);
114
+ }
45
115
  }
46
- return await fetch(url, {
47
- method: "POST",
48
- headers: {
49
- "Content-Type": "application/json",
50
- ...(config.debug ? { "Edgee-Debug": "true" } : {}),
51
- },
52
- body: JSON.stringify(event),
53
- });
54
116
  }
55
- else if (eventToSend.type === "user") {
56
- const event = {
57
- data_collection: {
58
- context: eventToSend.context,
59
- events: [
60
- {
61
- type: "user",
62
- data: eventToSend.data,
63
- components: eventToSend.components,
64
- },
65
- ],
66
- },
67
- };
117
+ catch (error) {
118
+ (0, utils_1.logError)("[Debug] Failed to handle response.", error);
119
+ }
120
+ return;
121
+ };
122
+ exports.sendPayload = sendPayload;
123
+ /**
124
+ * Sends an event to the Edgee API
125
+ */
126
+ const uploadEvent = async (config, event) => {
127
+ const payload = buildEventPayload(event);
128
+ await (0, exports.sendPayload)(config, payload);
129
+ return;
130
+ };
131
+ exports.uploadEvent = uploadEvent;
132
+ /**
133
+ * Handles response data: stores IDs, handles cookies, and logs events
134
+ * Similar to the JS SDK handleResponse function
135
+ */
136
+ const handleResponse = async (data, config) => {
137
+ let events = data;
138
+ // Store edgeeId and userId from response
139
+ // Convert to string if needed (API might return numbers)
140
+ if (data.e) {
141
+ const edgeeId = String(data.e);
142
+ await edgee_store_1.edgeeStore.setEdgeeId(edgeeId);
68
143
  if (config.debug) {
69
- // eslint-disable-next-line no-console
70
- console.log("[Edgee RN] sending", { url, event });
144
+ (0, utils_1.log)(config, `Set edgeeId: ${edgeeId}`);
71
145
  }
72
- return await fetch(url, {
73
- method: "POST",
74
- headers: {
75
- "Content-Type": "application/json",
76
- ...(config.debug ? { "Edgee-Debug": "true" } : {}),
77
- },
78
- body: JSON.stringify(event),
79
- });
80
146
  }
81
- else if (eventToSend.type === "screen") {
82
- const event = {
83
- data_collection: {
84
- context: eventToSend.context,
85
- events: [
86
- {
87
- type: "track",
88
- data: { ...eventToSend.data, screen_name: eventToSend.name },
89
- components: eventToSend.components,
90
- },
91
- ],
92
- },
93
- };
147
+ if (data.u) {
148
+ const userId = String(data.u);
149
+ await edgee_store_1.edgeeStore.setUserId(userId);
94
150
  if (config.debug) {
95
- // eslint-disable-next-line no-console
96
- console.log("[Edgee RN] sending", { url, event });
151
+ (0, utils_1.log)(config, `Set userId: ${userId}`);
97
152
  }
98
- return await fetch(url, {
99
- method: "POST",
100
- headers: {
101
- "Content-Type": "application/json",
102
- ...(config.debug ? { "Edgee-Debug": "true" } : {}),
103
- },
104
- body: JSON.stringify(event),
105
- });
106
153
  }
107
- else {
108
- throw new Error("Invalid event type");
154
+ // Extract events if present
155
+ if (data.events) {
156
+ events = data.events;
109
157
  }
158
+ // Log events if debug is enabled (matching JS SDK format)
159
+ if (events && Array.isArray(events) && events.length > 0) {
160
+ for (let i = 0; i < events.length; i++) {
161
+ (0, utils_1.log)(config, "○ " + events[i].type + " event (client):", events[i]);
162
+ }
163
+ }
164
+ return events;
110
165
  };
111
- exports.uploadEvent = uploadEvent;
package/dist/consent.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ConsentStatus } from "./index";
1
+ export type ConsentStatus = "granted" | "denied" | "pending";
2
2
  /**
3
3
  * Simple consent manager that works with existing EdgeeClient
4
4
  * Stores consent status and provides utilities for consent management
@@ -35,10 +35,6 @@ export declare class EdgeeConsent {
35
35
  * Check if consent is pending
36
36
  */
37
37
  isPending(): boolean;
38
- /**
39
- * Check if we should allow tracking
40
- */
41
- canTrack(): boolean;
42
38
  /**
43
39
  * Listen for consent changes
44
40
  */
@@ -54,43 +50,3 @@ export declare class EdgeeConsent {
54
50
  * This allows you to manage consent across your app without passing it around
55
51
  */
56
52
  export declare const edgeeConsent: EdgeeConsent;
57
- /**
58
- * Consent utilities
59
- */
60
- export declare const ConsentUtils: {
61
- /**
62
- * Initialize consent (call this once in your app)
63
- */
64
- init(): Promise<void>;
65
- /**
66
- * Set consent status
67
- */
68
- setConsent(status: ConsentStatus): Promise<void>;
69
- /**
70
- * Get current consent
71
- */
72
- getConsent(): ConsentStatus | null;
73
- /**
74
- * Check if can track
75
- */
76
- canTrack(): boolean;
77
- /**
78
- * Check consent status
79
- */
80
- hasConsent(): boolean;
81
- isGranted(): boolean;
82
- isDenied(): boolean;
83
- isPending(): boolean;
84
- /**
85
- * Listen for changes
86
- */
87
- onChange(callback: (status: ConsentStatus | null) => void): () => void;
88
- /**
89
- * Reset consent
90
- */
91
- reset(): Promise<void>;
92
- /**
93
- * Send consent event to Edgee using the new consent method
94
- */
95
- sendConsentEvent(edgeeClient: any, status: ConsentStatus): Promise<void>;
96
- };