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.
- package/README.md +1 -2
- package/dist/api.d.ts +32 -0
- package/dist/api.js +111 -0
- package/dist/consent.d.ts +96 -0
- package/dist/consent.js +220 -0
- package/dist/core/context.d.ts +41 -0
- package/dist/core/context.js +90 -0
- package/dist/core/edgee-store.d.ts +21 -0
- package/dist/core/edgee-store.js +53 -0
- package/dist/core/query-builder.d.ts +8 -0
- package/dist/core/query-builder.js +21 -0
- package/dist/core/queue.d.ts +25 -0
- package/dist/core/queue.js +155 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +321 -0
- package/dist/native-context.d.ts +13 -0
- package/dist/native-context.js +106 -0
- package/dist/navigation/expo-router.d.ts +4 -0
- package/dist/navigation/expo-router.js +21 -0
- package/dist/navigation/index.d.ts +2 -0
- package/dist/navigation/index.js +18 -0
- package/dist/navigation/react-navigation.d.ts +9 -0
- package/dist/navigation/react-navigation.js +36 -0
- package/dist/react.d.ts +24 -0
- package/dist/react.js +111 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.js +2 -0
- package/package.json +1 -1
|
@@ -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;
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
+
}
|