react-native-edgee 1.0.0 → 1.0.1

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.
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QueryBuilder = void 0;
4
+ class QueryBuilder {
5
+ constructor(config, store) {
6
+ this.config = config;
7
+ this.store = store;
8
+ }
9
+ async getUrl() {
10
+ const { edgeeId, userId } = await this.store.getContext();
11
+ const params = [];
12
+ if (edgeeId)
13
+ params.push(`e=${encodeURIComponent(edgeeId)}`);
14
+ if (userId)
15
+ params.push(`u=${encodeURIComponent(userId)}`);
16
+ return params.length
17
+ ? `${this.config.host}/_edgee/csevent?${params.join("&")}`
18
+ : `${this.config.host}/_edgee/csevent`;
19
+ }
20
+ }
21
+ exports.QueryBuilder = QueryBuilder;
@@ -0,0 +1,25 @@
1
+ import { EdgeeConfig } from "..";
2
+ import { EdgeeEvent } from "../api";
3
+ import { EdgeeStore } from "./edgee-store";
4
+ import { QueryBuilder } from "./query-builder";
5
+ export declare class EventQueue {
6
+ private store;
7
+ private queryBuilder;
8
+ private config;
9
+ private q;
10
+ private ready;
11
+ private online;
12
+ private flushing;
13
+ private unsubscribe?;
14
+ constructor(store: EdgeeStore, config: EdgeeConfig, queryBuilder: QueryBuilder);
15
+ destroy(): void;
16
+ setReady(val: boolean): void;
17
+ enqueue(item: EdgeeEvent): void;
18
+ /**
19
+ * Send a direct payload (used for consent events)
20
+ * This bypasses the normal event structure and sends raw payload
21
+ */
22
+ sendEvent(payload: any): Promise<void>;
23
+ private shouldFlush;
24
+ flush(): Promise<void>;
25
+ }
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EventQueue = void 0;
7
+ const netinfo_1 = __importDefault(require("@react-native-community/netinfo"));
8
+ const api_1 = require("../api");
9
+ class EventQueue {
10
+ constructor(store, config, queryBuilder) {
11
+ this.q = [];
12
+ this.ready = false;
13
+ this.online = false;
14
+ this.flushing = false;
15
+ this.store = store;
16
+ this.config = config;
17
+ this.queryBuilder = queryBuilder;
18
+ // Track connectivity
19
+ this.unsubscribe = netinfo_1.default.addEventListener((state) => {
20
+ this.online = !!state.isConnected && !!state.isInternetReachable;
21
+ if (this.shouldFlush())
22
+ void this.flush();
23
+ });
24
+ void netinfo_1.default.fetch().then((state) => {
25
+ this.online = !!state.isConnected && !!state.isInternetReachable;
26
+ });
27
+ void this.store.getPendingEvents().then((events) => {
28
+ this.q = events;
29
+ this.ready = true;
30
+ });
31
+ }
32
+ destroy() {
33
+ var _a;
34
+ (_a = this.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(this);
35
+ }
36
+ setReady(val) {
37
+ this.ready = val;
38
+ if (this.shouldFlush())
39
+ void this.flush();
40
+ }
41
+ enqueue(item) {
42
+ this.q.push(item);
43
+ if (this.config.debug) {
44
+ // eslint-disable-next-line no-console
45
+ console.log("[Edgee RN] enqueue", item);
46
+ }
47
+ void this.store.addEvent(item);
48
+ if (this.shouldFlush())
49
+ void this.flush();
50
+ }
51
+ /**
52
+ * Send a direct payload (used for consent events)
53
+ * This bypasses the normal event structure and sends raw payload
54
+ */
55
+ async sendEvent(payload) {
56
+ if (!this.online) {
57
+ if (this.config.debug) {
58
+ console.log("[Edgee RN] Offline - queuing direct payload");
59
+ }
60
+ // For direct payloads, we can't easily queue them in the current structure
61
+ // So we'll send them when we come back online
62
+ return;
63
+ }
64
+ try {
65
+ const url = await this.queryBuilder.getUrl();
66
+ if (this.config.debug) {
67
+ console.log("[Edgee RN] sending direct payload", { url, payload });
68
+ }
69
+ const response = await fetch(url, {
70
+ method: "POST",
71
+ headers: {
72
+ "Content-Type": "application/json",
73
+ ...(this.config.debug ? { "Edgee-Debug": "true" } : {}),
74
+ },
75
+ body: JSON.stringify(payload),
76
+ });
77
+ const text = await response.text().catch(() => "");
78
+ if (this.config.debug) {
79
+ console.log("[Edgee RN] direct payload response", {
80
+ status: response.status,
81
+ ok: response.ok,
82
+ body: text,
83
+ });
84
+ }
85
+ // Handle ID updates from response
86
+ try {
87
+ const data = text ? JSON.parse(text) : null;
88
+ if (data && (data.e || data.u)) {
89
+ if (data.e)
90
+ await this.store.setEdgeeId(data.e);
91
+ if (data.u)
92
+ await this.store.setUserId(data.u);
93
+ }
94
+ }
95
+ catch (e) {
96
+ if (this.config.debug)
97
+ console.log("persist ids error", e);
98
+ }
99
+ }
100
+ catch (error) {
101
+ console.warn("[Edgee RN] Failed to send direct payload:", error);
102
+ throw error;
103
+ }
104
+ }
105
+ shouldFlush() {
106
+ return this.ready && this.online && this.q.length > 0;
107
+ }
108
+ async flush() {
109
+ if (this.flushing || !this.shouldFlush())
110
+ return;
111
+ this.flushing = true;
112
+ const items = [...this.q];
113
+ try {
114
+ for (const item of items) {
115
+ const url = await this.queryBuilder.getUrl();
116
+ const resp = await (0, api_1.uploadEvent)(url, this.config, item);
117
+ const text = await resp.text().catch(() => "");
118
+ if (this.config.debug) {
119
+ // eslint-disable-next-line no-console
120
+ console.log("[Edgee RN] response", {
121
+ status: resp.status,
122
+ ok: resp.ok,
123
+ body: text,
124
+ });
125
+ }
126
+ try {
127
+ const data = text ? JSON.parse(text) : null;
128
+ if (data && (data.e || data.u)) {
129
+ if (data.e)
130
+ await this.store.setEdgeeId(data.e);
131
+ if (data.u)
132
+ await this.store.setUserId(data.u);
133
+ }
134
+ }
135
+ catch (e) {
136
+ if (this.config.debug)
137
+ console.log("persist ids error", e);
138
+ }
139
+ }
140
+ this.q = [];
141
+ await this.store.clearEvents();
142
+ }
143
+ catch (error) {
144
+ console.log("flush error", error);
145
+ this.q = [];
146
+ await this.store.clearEvents();
147
+ }
148
+ finally {
149
+ this.flushing = false;
150
+ if (this.shouldFlush())
151
+ void this.flush(); // Drain if new items arrived
152
+ }
153
+ }
154
+ }
155
+ exports.EventQueue = EventQueue;
@@ -0,0 +1,36 @@
1
+ export type ConsentStatus = "granted" | "denied" | "pending";
2
+ export type EdgeeConfig = {
3
+ host: string;
4
+ debug?: boolean;
5
+ collectDeviceId?: boolean;
6
+ };
7
+ type Components = Record<string, boolean> | undefined;
8
+ export declare class EdgeeClient {
9
+ private appState;
10
+ private store;
11
+ private queue;
12
+ private queryBuilder;
13
+ private appStateSubscription;
14
+ private config;
15
+ constructor(config: EdgeeConfig);
16
+ private handleAppStateChange;
17
+ track(name: string, data: object, components?: Components): Promise<void>;
18
+ user(data: object, components?: Components): Promise<void>;
19
+ screen(screenName: string, data: object, components?: Components): Promise<void>;
20
+ setConsent(status: ConsentStatus): Promise<void>;
21
+ getConsent(): ConsentStatus | null;
22
+ hasConsent(): boolean;
23
+ canTrack(): boolean;
24
+ resetConsent(): Promise<void>;
25
+ onConsentChange(callback: (status: ConsentStatus | null) => void): () => void;
26
+ /**
27
+ * Send consent event directly to Edgee (matches web SDK format)
28
+ */
29
+ consent(status: ConsentStatus): Promise<void>;
30
+ }
31
+ export * as navigation from "./navigation";
32
+ export { EdgeeAutoTracker, EdgeeProvider, useEdgee, useEdgeeConsent, } from "./react";
33
+ export type { EdgeeClientContext, EdgeeFullContext, EdgeePageContext, } from "./core/context";
34
+ export { clearContextCache, getNativeContext, isNativeModuleAvailable, } from "./native-context";
35
+ export type { EdgeeNativeContext, EdgeeNativeContextConfig, EdgeeReactNativeModule, } from "./types";
36
+ export { ConsentUtils, EdgeeConsent, edgeeConsent } from "./consent";
package/dist/index.js ADDED
@@ -0,0 +1,321 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.edgeeConsent = exports.EdgeeConsent = exports.ConsentUtils = exports.isNativeModuleAvailable = exports.getNativeContext = exports.clearContextCache = exports.useEdgeeConsent = exports.useEdgee = exports.EdgeeProvider = exports.EdgeeAutoTracker = exports.navigation = exports.EdgeeClient = void 0;
37
+ const react_native_1 = require("react-native");
38
+ const api_1 = require("./api");
39
+ const consent_1 = require("./consent");
40
+ const context_1 = require("./core/context");
41
+ const edgee_store_1 = require("./core/edgee-store");
42
+ const query_builder_1 = require("./core/query-builder");
43
+ const queue_1 = require("./core/queue");
44
+ const native_context_1 = require("./native-context");
45
+ /**
46
+ * Extract native context properties to include in event data under a sub-object
47
+ */
48
+ const extractNativeProperties = (nativeContext) => {
49
+ if (!nativeContext)
50
+ return {};
51
+ return {
52
+ native_context: {
53
+ // Device information
54
+ device_id: nativeContext.deviceId,
55
+ device_name: nativeContext.deviceName,
56
+ device_type: nativeContext.deviceType,
57
+ manufacturer: nativeContext.manufacturer,
58
+ model: nativeContext.model,
59
+ // System information
60
+ os_name: nativeContext.osName,
61
+ os_version: nativeContext.osVersion,
62
+ // App information
63
+ app_name: nativeContext.appName,
64
+ app_version: nativeContext.appVersion,
65
+ build_number: nativeContext.buildNumber,
66
+ bundle_id: nativeContext.bundleId,
67
+ // Hardware capabilities
68
+ is_tablet: nativeContext.isTablet,
69
+ is_simulator: nativeContext.isSimulator,
70
+ is_emulator: nativeContext.isEmulator,
71
+ is_rooted: nativeContext.isRooted,
72
+ is_jailbroken: nativeContext.isJailbroken,
73
+ // System metrics
74
+ total_memory_mb: nativeContext.totalMemoryMB,
75
+ free_memory_mb: nativeContext.freeMemoryMB,
76
+ max_memory_mb: nativeContext.maxMemoryMB,
77
+ used_memory_mb: nativeContext.usedMemoryMB,
78
+ available_memory_mb: nativeContext.availableMemoryMB,
79
+ free_storage_mb: nativeContext.freeStorageMB,
80
+ total_storage_mb: nativeContext.totalStorageMB,
81
+ used_storage_mb: nativeContext.usedStorageMB,
82
+ battery_level: nativeContext.batteryLevel,
83
+ battery_state: nativeContext.batteryState,
84
+ system_uptime: nativeContext.systemUptime,
85
+ low_power_mode: nativeContext.lowPowerMode,
86
+ // Network information
87
+ network_type: nativeContext.networkType,
88
+ carrier_name: nativeContext.carrierName,
89
+ radio_technology: nativeContext.radioTechnology,
90
+ // Locale information
91
+ locale: nativeContext.locale,
92
+ language: nativeContext.language,
93
+ country: nativeContext.country,
94
+ timezone: nativeContext.timezone,
95
+ // Privacy information
96
+ advertising_id: nativeContext.advertisingId,
97
+ ad_tracking_enabled: nativeContext.adTrackingEnabled,
98
+ tracking_status: nativeContext.trackingStatus,
99
+ // Additional information
100
+ user_agent: nativeContext.userAgent,
101
+ first_install_time: nativeContext.firstInstallTime,
102
+ last_update_time: nativeContext.lastUpdateTime,
103
+ },
104
+ };
105
+ };
106
+ let initialized = false;
107
+ let config = null;
108
+ const STORAGE_KEYS = {
109
+ edgeeId: "_edgee",
110
+ userId: "_edgee_u",
111
+ };
112
+ class EdgeeClient {
113
+ constructor(config) {
114
+ // current app state
115
+ this.appState = "unknown";
116
+ this.appStateSubscription = null;
117
+ this.handleAppStateChange = (nextAppState) => {
118
+ if (["inactive", "background"].includes(this.appState) &&
119
+ nextAppState === "active") {
120
+ this.track("application_opened", {
121
+ from_background: true,
122
+ });
123
+ }
124
+ else if ((this.appState === "active" || this.appState === "unknown") && // Check if appState is 'active' or 'unknown'
125
+ ["inactive", "background"].includes(nextAppState)) {
126
+ // Check if next app state is 'inactive' or 'background'
127
+ this.track("application_backgrounded", {});
128
+ }
129
+ this.appState = nextAppState;
130
+ };
131
+ this.config = config;
132
+ this.store = new edgee_store_1.EdgeeStore();
133
+ void this.store.init();
134
+ this.queryBuilder = new query_builder_1.QueryBuilder(config, this.store);
135
+ this.queue = new queue_1.EventQueue(this.store, config, this.queryBuilder);
136
+ this.appStateSubscription = react_native_1.AppState.addEventListener("change", this.handleAppStateChange);
137
+ // Initialize consent system
138
+ void consent_1.ConsentUtils.init();
139
+ }
140
+ async track(name, data, components) {
141
+ // Check consent before tracking
142
+ if (!consent_1.ConsentUtils.canTrack()) {
143
+ if (this.config.debug) {
144
+ console.log(`[Edgee] Event "${name}" not tracked - consent not granted`);
145
+ }
146
+ return;
147
+ }
148
+ const context = await (0, context_1.getContext)(this.config.collectDeviceId);
149
+ // Get native context properties if available and collectDeviceId is enabled
150
+ let nativeProperties = {};
151
+ if (this.config.collectDeviceId && (0, native_context_1.isNativeModuleAvailable)()) {
152
+ try {
153
+ const nativeContext = await (0, native_context_1.getNativeContext)({
154
+ collectDeviceId: this.config.collectDeviceId,
155
+ });
156
+ nativeProperties = extractNativeProperties(nativeContext);
157
+ }
158
+ catch (error) {
159
+ if (this.config.debug) {
160
+ console.warn("[Edgee] Failed to get native context for event properties:", error);
161
+ }
162
+ }
163
+ }
164
+ // Merge native properties with event data
165
+ const enhancedData = {
166
+ ...data,
167
+ ...nativeProperties,
168
+ };
169
+ const event = (0, api_1.createTrackEvent)({
170
+ name,
171
+ data: enhancedData,
172
+ components,
173
+ context,
174
+ });
175
+ this.queue.enqueue(event);
176
+ }
177
+ async user(data, components) {
178
+ // Check consent before tracking
179
+ if (!consent_1.ConsentUtils.canTrack()) {
180
+ if (this.config.debug) {
181
+ console.log(`[Edgee] User event not tracked - consent not granted`);
182
+ }
183
+ return;
184
+ }
185
+ const context = await (0, context_1.getContext)(this.config.collectDeviceId);
186
+ // Get native context properties if available and collectDeviceId is enabled
187
+ let nativeProperties = {};
188
+ if (this.config.collectDeviceId && (0, native_context_1.isNativeModuleAvailable)()) {
189
+ try {
190
+ const nativeContext = await (0, native_context_1.getNativeContext)({
191
+ collectDeviceId: this.config.collectDeviceId,
192
+ });
193
+ nativeProperties = extractNativeProperties(nativeContext);
194
+ }
195
+ catch (error) {
196
+ if (this.config.debug) {
197
+ console.warn("[Edgee] Failed to get native context for user properties:", error);
198
+ }
199
+ }
200
+ }
201
+ // Merge native properties with user data
202
+ const enhancedData = {
203
+ ...data,
204
+ ...nativeProperties,
205
+ };
206
+ const event = (0, api_1.createUserEvent)({
207
+ data: enhancedData,
208
+ components,
209
+ context,
210
+ });
211
+ this.queue.enqueue(event);
212
+ }
213
+ async screen(screenName, data, components) {
214
+ // Check consent before tracking
215
+ if (!consent_1.ConsentUtils.canTrack()) {
216
+ if (this.config.debug) {
217
+ console.log(`[Edgee] Screen "${screenName}" not tracked - consent not granted`);
218
+ }
219
+ return;
220
+ }
221
+ const context = await (0, context_1.getContext)(this.config.collectDeviceId);
222
+ // Get native context properties if available and collectDeviceId is enabled
223
+ let nativeProperties = {};
224
+ if (this.config.collectDeviceId && (0, native_context_1.isNativeModuleAvailable)()) {
225
+ try {
226
+ const nativeContext = await (0, native_context_1.getNativeContext)({
227
+ collectDeviceId: this.config.collectDeviceId,
228
+ });
229
+ nativeProperties = extractNativeProperties(nativeContext);
230
+ }
231
+ catch (error) {
232
+ if (this.config.debug) {
233
+ console.warn("[Edgee] Failed to get native context for screen properties:", error);
234
+ }
235
+ }
236
+ }
237
+ // Merge native properties with screen data
238
+ const enhancedData = {
239
+ ...data,
240
+ screen_name: screenName,
241
+ ...nativeProperties,
242
+ };
243
+ const event = (0, api_1.createTrackEvent)({
244
+ name: "screen",
245
+ data: enhancedData,
246
+ components,
247
+ context,
248
+ });
249
+ this.queue.enqueue(event);
250
+ }
251
+ // Consent management methods
252
+ async setConsent(status) {
253
+ await consent_1.ConsentUtils.setConsent(status);
254
+ // Send consent event to server
255
+ await consent_1.ConsentUtils.sendConsentEvent(this, status);
256
+ if (this.config.debug) {
257
+ console.log(`[Edgee] Consent set to: ${status}`);
258
+ }
259
+ }
260
+ getConsent() {
261
+ return consent_1.ConsentUtils.getConsent();
262
+ }
263
+ hasConsent() {
264
+ return consent_1.ConsentUtils.hasConsent();
265
+ }
266
+ canTrack() {
267
+ return consent_1.ConsentUtils.canTrack();
268
+ }
269
+ async resetConsent() {
270
+ await consent_1.ConsentUtils.reset();
271
+ if (this.config.debug) {
272
+ console.log(`[Edgee] Consent reset`);
273
+ }
274
+ }
275
+ onConsentChange(callback) {
276
+ return consent_1.ConsentUtils.onChange(callback);
277
+ }
278
+ /**
279
+ * Send consent event directly to Edgee (matches web SDK format)
280
+ */
281
+ async consent(status) {
282
+ // Validate consent status
283
+ if (!["granted", "denied", "pending"].includes(status)) {
284
+ throw new Error(`Invalid consent: ${status}. Use 'granted', 'denied', or 'pending'`);
285
+ }
286
+ // Store consent locally
287
+ await consent_1.ConsentUtils.setConsent(status);
288
+ // Send consent event using web SDK format
289
+ const payload = {
290
+ data_collection: {
291
+ consent: status,
292
+ },
293
+ };
294
+ try {
295
+ await this.queue.sendEvent(payload);
296
+ if (this.config.debug) {
297
+ console.log(`[Edgee] Consent sent to server: ${status}`);
298
+ }
299
+ }
300
+ catch (error) {
301
+ console.warn("[Edgee] Failed to send consent event:", error);
302
+ throw error;
303
+ }
304
+ }
305
+ }
306
+ exports.EdgeeClient = EdgeeClient;
307
+ exports.navigation = __importStar(require("./navigation"));
308
+ var react_1 = require("./react");
309
+ Object.defineProperty(exports, "EdgeeAutoTracker", { enumerable: true, get: function () { return react_1.EdgeeAutoTracker; } });
310
+ Object.defineProperty(exports, "EdgeeProvider", { enumerable: true, get: function () { return react_1.EdgeeProvider; } });
311
+ Object.defineProperty(exports, "useEdgee", { enumerable: true, get: function () { return react_1.useEdgee; } });
312
+ Object.defineProperty(exports, "useEdgeeConsent", { enumerable: true, get: function () { return react_1.useEdgeeConsent; } });
313
+ var native_context_2 = require("./native-context");
314
+ Object.defineProperty(exports, "clearContextCache", { enumerable: true, get: function () { return native_context_2.clearContextCache; } });
315
+ Object.defineProperty(exports, "getNativeContext", { enumerable: true, get: function () { return native_context_2.getNativeContext; } });
316
+ Object.defineProperty(exports, "isNativeModuleAvailable", { enumerable: true, get: function () { return native_context_2.isNativeModuleAvailable; } });
317
+ // Export consent functionality
318
+ var consent_2 = require("./consent");
319
+ Object.defineProperty(exports, "ConsentUtils", { enumerable: true, get: function () { return consent_2.ConsentUtils; } });
320
+ Object.defineProperty(exports, "EdgeeConsent", { enumerable: true, get: function () { return consent_2.EdgeeConsent; } });
321
+ Object.defineProperty(exports, "edgeeConsent", { enumerable: true, get: function () { return consent_2.edgeeConsent; } });
@@ -0,0 +1,13 @@
1
+ import type { EdgeeNativeContext, EdgeeNativeContextConfig } from "./types";
2
+ /**
3
+ * Get comprehensive device and app context from native modules
4
+ */
5
+ export declare function getNativeContext(config?: EdgeeNativeContextConfig): Promise<EdgeeNativeContext>;
6
+ /**
7
+ * Clear cached context (useful for testing or when context might change)
8
+ */
9
+ export declare function clearContextCache(): void;
10
+ /**
11
+ * Check if native module is available
12
+ */
13
+ export declare function isNativeModuleAvailable(): boolean;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNativeContext = getNativeContext;
4
+ exports.clearContextCache = clearContextCache;
5
+ exports.isNativeModuleAvailable = isNativeModuleAvailable;
6
+ const react_native_1 = require("react-native");
7
+ const LINKING_ERROR = `The package 'react-native-edgee' doesn't seem to be linked. Make sure: \n\n` +
8
+ react_native_1.Platform.select({ ios: "- You have run 'pod install'\n", default: "" }) +
9
+ "- You rebuilt the app after installing the package\n" +
10
+ "- You are not using Expo managed workflow\n";
11
+ const EdgeeReactNative = react_native_1.NativeModules.EdgeeReactNative
12
+ ? react_native_1.NativeModules.EdgeeReactNative
13
+ : new Proxy({}, {
14
+ get() {
15
+ throw new Error(LINKING_ERROR);
16
+ },
17
+ });
18
+ let cachedContext = null;
19
+ let contextPromise = null;
20
+ /**
21
+ * Get comprehensive device and app context from native modules
22
+ */
23
+ async function getNativeContext(config = {}) {
24
+ // Return cached context if available and no device ID collection requested
25
+ if (cachedContext && !config.collectDeviceId) {
26
+ return cachedContext;
27
+ }
28
+ // Return ongoing promise if one exists
29
+ if (contextPromise) {
30
+ return contextPromise;
31
+ }
32
+ contextPromise = EdgeeReactNative.getContextInfo(config)
33
+ .then((context) => {
34
+ // Cache context if no sensitive data (device ID) was requested
35
+ if (!config.collectDeviceId) {
36
+ cachedContext = context;
37
+ }
38
+ contextPromise = null;
39
+ return context;
40
+ })
41
+ .catch((error) => {
42
+ contextPromise = null;
43
+ console.warn("Failed to get native context:", error);
44
+ // Return fallback context
45
+ return getFallbackContext();
46
+ });
47
+ return contextPromise;
48
+ }
49
+ /**
50
+ * Get fallback context when native module is not available
51
+ */
52
+ function getFallbackContext() {
53
+ const { width, height } = require("react-native").Dimensions.get("window");
54
+ const { scale } = require("react-native").PixelRatio.get();
55
+ return {
56
+ // App information
57
+ appName: "Unknown App",
58
+ appVersion: "1.0.0",
59
+ buildNumber: "1",
60
+ bundleId: "com.unknown.app",
61
+ // Device information
62
+ deviceName: react_native_1.Platform.OS === "ios" ? "iPhone" : "Android Device",
63
+ deviceType: react_native_1.Platform.OS,
64
+ manufacturer: react_native_1.Platform.OS === "ios" ? "Apple" : "Unknown",
65
+ model: "Unknown",
66
+ // System information
67
+ osName: react_native_1.Platform.OS === "ios" ? "iOS" : "Android",
68
+ osVersion: react_native_1.Platform.Version.toString(),
69
+ // Locale and timezone
70
+ locale: "en-US",
71
+ language: "en",
72
+ country: "US",
73
+ timezone: "America/New_York",
74
+ // Screen information
75
+ screenWidth: Math.round(width * scale),
76
+ screenHeight: Math.round(height * scale),
77
+ screenDensity: scale,
78
+ // Network information
79
+ networkType: "unknown",
80
+ // Hardware capabilities
81
+ isTablet: false,
82
+ // System metrics
83
+ totalMemoryMB: 0,
84
+ // Privacy information
85
+ adTrackingEnabled: false,
86
+ trackingStatus: "unknown",
87
+ };
88
+ }
89
+ /**
90
+ * Clear cached context (useful for testing or when context might change)
91
+ */
92
+ function clearContextCache() {
93
+ cachedContext = null;
94
+ contextPromise = null;
95
+ }
96
+ /**
97
+ * Check if native module is available
98
+ */
99
+ function isNativeModuleAvailable() {
100
+ try {
101
+ return !!react_native_1.NativeModules.EdgeeReactNative;
102
+ }
103
+ catch {
104
+ return false;
105
+ }
106
+ }
@@ -0,0 +1,4 @@
1
+ import type { EdgeeClient } from "../index";
2
+ export declare function EdgeeExpoRouterTracker({ edgee, }: {
3
+ edgee: Pick<EdgeeClient, "screen">;
4
+ }): null;